用Abp实现两步验证(Two-Factor Authentication,2FA)登录(二):Vue网页端开发

2023-05-25编程技术234870

@

目录
发送验证码
登录
退出登录
界面控件
获取用户信息功能
项目地址

前端代码的框架采用vue.js + elementUI 这套较为简单的方式实现,以及typescript语法更方便阅读。

首先添加全局对象:

loginForm: 登录表单对象

twoFactorData: 两步验证数据,

showTwoFactorSuccess: 是否显示两步验证成功提示

loginForm: {
//登录对象
username: "",
password: "",
twoFactorAuthenticationToken: "",
twoFactorAuthenticationProvider: "Phone",
},
twoFactorData: null,
showTwoFactorSuccess: false,

发送验证码

编写发送验证码函数sendVerificationCode,发送验证码后,启动定时器,60秒后可以再次发送验证码。

   async sendVerificationCode() {
this.smsSendCd = 60;
this.timer = setInterval(() => {
this.smsSendCd--;
if (this.smsSendCd <= 0) {
clearInterval(this.timer);
}
}, 1000);
await request(
`${this.host}api/TokenAuth/SendTwoFactorAuthenticateCaptcha`,
"post",
{
provider: "Phone",
userId: this.twoFactorData.userId,
}
)
.catch((re) => {
var res = re.response.data;
this.errorMessage(res.error.message);
})
.then((re) => {
var res = re.data.result;
this.showTwoFactorSuccess = true;
this.showTwoFactorSuccess = false;
this.successMessage("发送验证码成功");
});
},

request 是利用axios库发送带有访问凭证Header请求功能的封装 ,ajaxRequest.ts请参考博文使用 Abp.Zero 搭建第三方登录模块(三):网页端开发

这里使用js-cookie库获取cookie中的访问凭证,并添加到Header中

import { request } from "@/ajaxRequire";
import Cookies from "js-cookie"; const tokenKey = "main_token";
const setToken = (token: string) => Cookies.set(tokenKey, token);
const cleanToken = () => Cookies.remove(tokenKey);
const getToken = () => Cookies.get(tokenKey);

登录

编写登录函数handleLogin:

 async handleLogin() {
this.loading = true; var userNameOrEmailAddress = this.loginForm.username;
var password = this.loginForm.password; var twoFactorAuthenticationToken =
this.loginForm.twoFactorAuthenticationToken;
var twoFactorAuthenticationProvider =
this.loginForm.twoFactorAuthenticationProvider; userNameOrEmailAddress = userNameOrEmailAddress.trim();
await request(`${this.host}api/TokenAuth/Authenticate`, "post", {
userNameOrEmailAddress,
password,
twoFactorAuthenticationToken,
twoFactorAuthenticationProvider,
})
.catch((re) => {
var res = re.response.data;
this.errorMessage(res.error.message);
})
.then(async (res) => {
var data = res.data.result;
if (data.requiresTwoFactorAuthenticate) {
this.twoFactorData = data;
} else {
setToken(data.accessToken);
setRememberClientToken(data.rememberClientToken);
await this.getCurrentUser();
}
})
.finally(() => {
setTimeout(() => {
this.loading = false;
}, 1.5 * 1000);
});
},

请注意,当需要进行两步验证时,requiresTwoFactorAuthenticate会返回true,同时返回

twoFactorAuthenticationProviders。

退出登录

登出, 将Token以及用户信息置空

<el-button
:loading="loading"
type="danger"
style="width: 100%"
@click.native.prevent="logout">
退出登录
</el-button>
logout() {
setToken(null);
this.token = null;
this.userInfo = null;
},

界面控件

在登录表单的HTML中,添加两步验证控件:

显示规则为,当需要两步验证时(即twoFactorData不为空),显示两步验证控件,否则显示登录控件。

根据twoFactorAuthenticationProviders。我们采用了两种方式,一种是短信验证码,一种是邮箱验证码,这里我们采用了elementUI的tab组件,来实现两种方式的切换。

     <el-form
ref="loginForm"
:model="loginForm"
class="login-form"
autocomplete="on"
label-position="left"
>
<template v-if="twoFactorData == null">
...
</template>
<template v-else>
<p>您的账号开启了两步验证,请选择一种认证方式以继续登录</p>
<el-tabs
v-model="loginForm.twoFactorAuthenticationProvider"
tab-position="top"
>
<el-tab-pane
:lazy="true"
label="SMS短信验证"
name="Phone"
:disabled="
twoFactorData.twoFactorAuthenticationProviders.indexOf(
'Email'
) == -1
"
>
<el-row>
<el-col
:span="24"
style="
{
margin-bottom: 10px;
}
"
>
<el-alert
v-if="showTwoFactorSuccess"
title="验证码已发送至用户的手机号,请查收"
type="info"
>
</el-alert>
</el-col>
<el-col :span="24">
<el-form-item
class="item"
prop="twoFactorAuthenticationToken"
>
<el-input
v-model="loginForm.twoFactorAuthenticationToken"
:placeholder="'发送验证码后键入验证码'"
tabindex="2"
autocomplete="on"
@blur="capsTooltip = false"
>
<el-button
slot="append"
:disabled="smsSendCd > 0"
@click="sendVerificationCode"
>{{
smsSendCd == 0 ? "发送验证码" : smsSendCd + "后重试"
}}</el-button
>
</el-input>
</el-form-item>
</el-col>
</el-row>
</el-tab-pane> <el-tab-pane
:lazy="true"
label="邮箱验证"
name="Email"
:disabled="
twoFactorData.twoFactorAuthenticationProviders.indexOf(
'Email'
) == -1
"
>
<el-row>
<el-col :span="24">
<el-alert
v-if="showTwoFactorSuccess"
title="验证码已发送至登录用户对应的邮箱,请查收"
type="info"
>
</el-alert>
</el-col>
<el-col :span="24">
...
</el-col>
</el-row>
</el-tab-pane>
</el-tabs>
</template> <el-row type="flex" class="row-bg" justify="center" :gutter="10">
<el-col :span="10" v-if="twoFactorData != null">
<el-button
:loading="loading"
style="width: 100%"
@click.native.prevent="twoFactorData = null"
>
返回
</el-button>
</el-col>
<el-col :span="10">
<el-button
:loading="loading"
type="primary"
style="width: 100%"
@click.native.prevent="handleLogin"
>
{{ twoFactorData == null ? "登录" : "继续" }}
</el-button>
</el-col>
</el-row>
</el-form>

获取用户信息功能

登录成功后我们要拿到当前用户的信息,存入userInfo对象,并在页面上简单展示

<span>{{ userInfo }}</span>

创建一个获取当前用户的函数

async getCurrentUser() {
await request(
`${this.host}${this.prefix}/User/GetCurrentUser`,
"get",
null
)
.catch((re) => {
var res = re.response.data;
this.errorMessage(res.error.message);
})
.then(async (re) => {
var result = re.data.result as any;
this.userInfo = result;
this.token = getToken();
clearInterval(this.timer); this.smsSendCd = 0;
this.currentVerifyingType = null; this.successMessage("登录成功");
});
}

最终效果

项目地址

Github:matoapp-samples

用Abp实现两步验证(Two-Factor Authentication,2FA)登录(二):Vue网页端开发的相关教程结束。

本文地址:https://www.ufcn.cn/tutorials/2671357.html

如非特殊说明,本站内容均来自于网友自主分享,概不代表本站观点,如有任何问题我们都将在收到反馈后的第一时间进行处理!