首页 >> 大全

使用 Abp.Zero 搭建第三方登录模块(三):网页端开发

2023-09-15 大全 40 作者:考证青年

简短回顾一下网页端的流程,总的来说网页端的职责有三:

生成一个随机字符作为鉴权会话的临时Token, 生成一个小程序码, Token作为参数固化于小程序码当中监控整个鉴权过程状态,一旦状态变为(已授权)则获取小程序登录凭证code。调用完成登录。

上一章,我们介绍了服务端的开发,这次我们需要调用,,分别获取小程序码,和获取当前状态

首先使用vue-cli创建一个web项目,命名为mp-auth

vue create mp-auth

新建.ts,创建对象,这一对象将利用axios库发送带有访问凭证的的请求

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

import Cookies from "js-cookie";
import axios, {  CancelTokenSource } from 'axios'
//发送网络请求
const tokenKey = "main_token";
const getToken = () => Cookies.get(tokenKey);export const request = async (url: string, methods, data: any, onProgress?: (e) => void, cancelToken?: CancelTokenSource) => {let token = nulllet timeout = 3000;if (cancelToken) {token = cancelToken.tokentimeout = 0;}const service = axios.create()service.interceptors.request.use((config) => {const token = getToken();// Add X-Access-Token header to every request, you can add other custom headers hereif (token) {config.headers['X-XSRF-TOKEN'] = tokenconfig.headers['Authorization'] = 'Bearer ' + token}return config},(error) => {Promise.reject(error)})const re = await service.request({url: url,method: methods,data: data,cancelToken: token,timeout: timeout,onUploadProgress: function (progressEvent) { //原生获取上传进度的事件if (progressEvent.lengthComputable) {if (onProgress) {onProgress(progressEvent);}}},})return re as any;
}///获得取消令牌
export const getCancelToken = () => {const source = axios.CancelToken.source();return source;
}

回到App.vue

我们按照网页端这个三个职责的顺序,分步骤完成代码

生成Token

首先建立两个变量,存储当前的Token和状态枚举值

export default {name: "App",data: () => {return {wechatMiniappLoginToken: null,wechatMiniappLoginStatus: "WAIT",};},

中建立函数,这里使用8位随机数作为token值

  methods: {getToken() {if (this.wechatMiniappLoginToken == null) {var date = new Date();var token = `${(Math.random() * 100000000).toFixed(0).toString().padEnd(8, "0")}`;this.wechatMiniappLoginToken = token;}return this.wechatMiniappLoginToken;}}

生成小程序码

Html部分,插入一个图片,将token传入scene参数

第三方平台搭建__第三方登录接口

是你的服务地址前缀

prefix: "https://localhost:44311/api/services/app"

page为小程序中鉴权页面的路径,需注意的是在小程序未发布时无法跳转至页面,报错41030,若要使用扫码来跳转指定页面,小程序需要先发布

第三方平台搭建__第三方登录接口

miniappPage: "pages/login/index"

监控整个鉴权过程状态

首先需要一个函数,根据当前的Token获取当前鉴权状态,并且不断循环这一操作,这里编写start函数,并以每1秒钟轮询状态,代码如下:

   start() {clearInterval(this.timerId);this.timerId = setInterval(async () => {if (!this.loading) {this.loading = true;await request(`${this.prefix}/MiniProgram/GetToken?token=${this.wechatMiniappLoginToken}`,"get",null)            }}, 1000);},

在页面开始函数代码中调用这一函数

  created: function () {this.start();},

接下来处理轮询结果,如果没有拿到值,说明Token已过期,atus状态为""

          await request(`${this.prefix}/MiniProgram/GetToken?token=${this.wechatMiniappLoginToken}`,"get",null).then(async (re) => {if (re.data.result == null) {this.wechatMiniappLoginStatus = "EXPIRED";this.wechatMiniappLoginToken = null;this.loading = false;}

注意:

在后端项目的e.cs中,我们定义的

为5分钟,表明二维码的有效时间为5分钟。

public static TimeSpan TokenCacheDuration = TimeSpan.FromMinutes(5);

相应的Token为时,将ken置空,这一属性变动vue会通知img的src值变动而刷新小程序码,同时获取新的Token值赋值给ken,这也是刷新小程序码的逻辑

this.wechatMiniappLoginToken = null;

这样能以简单方式,实现二维码刷新功能。

界面中新建一个刷新小程序码的按钮:

      刷新

编写一个方法,在用于获取Code后,调用后端第三方登录接口,获取访问凭证存储于中

async externalLogin(userInfo: {authProvider: string;providerKey: string;providerAccessCode: string;}) {let authProvider = userInfo.authProvider;let providerKey = userInfo.providerKey;let providerAccessCode = userInfo.providerAccessCode;await request(`https://localhost:44311/api/TokenAuth/ExternalAuthenticate`,"post",{authProvider,providerKey,providerAccessCode,}).then(async (res) => {var data = res.data.result;setToken(data.accessToken);});},

定义函数,使用js-库将访问凭证写入浏览器中

const tokenKey = "main_token";
const setToken = (token: string) => Cookies.set(tokenKey, token);

第三方平台搭建_第三方登录接口_

在此之前我们需写一个参数传递对象,为了保留一定的扩展能力,data中我们定义,已经实现的微信小程序登录,则对应的值为“”,则为生成的Token值

      loginExternalForms: {WeChat: {authProvider: "WeChatAuthProvider",providerKey: "default",providerAccessCode: "",},},

接下来包装方法,在调用完成前后做一些操作,比如登录成功后,将调方法

为了保留一定的扩展能力,函数中我们保留参数,已实现的微信小程序登录函数调用时传递参数""

    async handleExternalLogin(authProvider) {// (this.$refs.baseForm as any).validate(async (valid) => {//   if (valid == null) {var currentForms = this.loginExternalForms[authProvider];this.loading = true;return await this.ExternalLogin(currentForms).then(async (re) => {return await request(`${this.prefix}/User/GetCurrentUser`,"get",null).then(async (re) => {var result = re.data.result as any;return await this.afterLoginSuccess(result);});});},async handleWxLogin(providerAccessCode) {this.loginExternalForms.WeChat.providerAccessCode = providerAccessCode;return await this.handleExternalLogin("WeChat");},

函数用于登录成功后的逻辑,停止计时器,并跳转页面,本实例仅做弹窗提示

    successMessage(value = "执行成功") {this.$notify({title: "成功",message: value,type: "success",});},    async afterLoginSuccess(userinfo) {clearInterval(this.timerId);this.successMessage("登录成功");this.userInfo = userinfo;},

继续编写start函数

如果拿到的token至不为空,则传递值给atus,当atus状态为""时调用函数:

              if (re.data.result == null) {this.wechatMiniappLoginStatus = "EXPIRED";this.wechatMiniappLoginToken = null;this.loading = false;} else {var result = re.data.result;this.wechatMiniappLoginStatus = result.status;if (this.wechatMiniappLoginStatus == "AUTHORIZED" &&result.providerAccessCode != null) {await this.handleWxLogin(result.providerAccessCode).then(() => {this.wechatMiniappLoginToken = null;this.loading = false;}).catch((e) => {this.wechatMiniappLoginToken = null;this.loading = false;clearInterval(this.timerId);});} else {this.loading = false;}}

接下来简单编写一个界面,

界面将清晰的反映atus各个状态时对应的UI交互:

WAIT(等待扫码):

(已扫码):

(已扫码):

完整的Html代码如下:


至此我们已完成网页端的开发工作

关于我们

最火推荐

小编推荐

联系我们


版权声明:本站内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 88@qq.com 举报,一经查实,本站将立刻删除。备案号:桂ICP备2021009421号
Powered By Z-BlogPHP.
复制成功
微信号:
我知道了