使用 Abp.Zero 搭建第三方登录模块(四):微信小程序开发
简短回顾一下微信小程序端的流程:
- 用户通过扫码进入小程序的鉴权页面,更新状态到ACCESSED已扫码
- 用户点击确认授权,微信通过wx.login()接口获取第三方登录的必要信息:Code登录凭证。
微信小程序主要为用户授权行为提供交互功能,用户在扫码之后,提供一个交互UI,如下:

在使用 Abp.Zero 搭建第三方登录模块(二):服务端开发 - 林晓lx - 博客园 (cnblogs.com)中介绍了服务端已经搭建的接口,这次我们将调用Access和Authenticate,分别调用来完成已扫码和已授权状态的更新。
项目搭建
首先使用vue-cli创建一个web项目,命名为mp-weixin
vue create -p dcloudio/uni-preset-vue mp-weixin

在Pages下创建login/index.vue页面,作为登录授权页
目录结构如下:

pages.json:
{
"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "uni-app"
}
},
{
"path": "pages/login/index",
"style": {
"navigationBarTitleText": "授权页"
}
}
],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "uni-app",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8"
}
}

login目录下新建ajaxRequire.ts, 创建request对象,这一对象将利用uni-axios-ts库发送ajax请求
import axios from 'uni-axios-ts'
//发送网络请求
export const request = async (url: string, methods, data: any, onProgress?: (e) => void, cancelToken?) => {
let token = null
let timeout = 3000;
if (cancelToken) {
token = cancelToken.token
timeout = 0;
}
const service = axios.create()
service.interceptors.request.use(
(config) => {
config.header['Content-Type'] = "application/json"
return config
},
(error) => {
Promise.reject(error)
}
)
const re = await service.request({
headers: { 'Content-Type': 'multipart/form-data' },
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;
}

index.vue中创建loginExternalForms作为参数传输对象
export default {
data() {
return {
loginExternalForms: {
WeChat: {
token: "",
providerAccessCode: "",
},
}
};
}
}

onLoad函数中,option存有扫描小程序码中的scene参数,将scene参数赋值给token变量
onLoad(option) {
this.loginExternalForms.WeChat.token = option.scene;
this.start();
},

start中我们调用Access接口,更改状态至ACCESSED(已扫码) ,若返回成功,则提示点用户点击确认授权,若返回的结果异常"WechatMiniProgramLoginInvalidToken"时,表明此时小程序码已过期,需在网页端更新小程序码。
async start() {
var currentForms = this.loginExternalForms["WeChat"];
this.loading = true;
await request(`${this.prefix}/MiniProgram/Access`, "post", currentForms)
.then((re) => {
this.successMessage("您已扫描二维码,请点击确认登录以完成");
})
.catch((c) => {
var err = c.response?.data?.error?.message;
if (err != null) {
if (err == "WechatMiniProgramLoginInvalidToken") {
this.isInvalid = true;
} else {
this.errorMessage(c.err);
}
}
})
.finally(() => {
setTimeout(() => {
this.loading = false;
}, 1.5 * 1000);
});
},

Prefix是你的服务地址前缀
prefix: "https://localhost:44311/api/services/app"

在Html中,我们创建授权登录与取消按钮,仅当isInvalid 为true时可以点击授权
<button
@click="handleWxLogin"
:disabled="isInvalid || loading"
class="sub-btn"
>
授权登录
</button>
<button @click="cancelWxLogin" :disabled="loading" class="sub-btn">
取消
</button>

创建 handleExternalLogin用于处理用户点击授权登录后的逻辑,调用Authenticate接口,更新状态至AUTHORIZED(已授权)在此之前需要调用uni.login获取小程序登录凭证code。
有关uni.login函数,请参考官方文档uni.login(OBJECT) | uni-app官网 (dcloud.io)
uniapp支持多种小程序,为了保留一定的扩展能力,handleExternalLogin函数中我们保留参数authProvider,已实现的微信小程序登录handleWxLogin函数调用时传递参数"WeChat",
async handleExternalLogin(authProvider) {
var currentForms = this.loginExternalForms[authProvider];
this.loading = true;
await request(
`${this.prefix}/MiniProgram/Authenticate`,
"post",
currentForms
)
.then((re) => {
uni.redirectTo({
url: "/pages/index/index",
});
})
.catch((c) => {
var err = c.response?.data?.error?.message;
if (err != null) {
if (err == "WechatMiniProgramLoginInvalidToken") {
this.isInvalid = true;
} else {
this.errorMessage(c.err);
}
}
setTimeout(() => {
this.loading = false;
}, 1.5 * 1000);
});
},
async handleWxLogin() {
const that = this;
uni.login({
provider: "weixin",
success: (loginRes) => {
that.loginExternalForms.WeChat.providerAccessCode = loginRes.code;
that.handleExternalLogin("WeChat");
},
});
},

创建取消登录函数
cancelWxLogin() {
uni.redirectTo({
url: "/pages/index/index",
});
},

执行成功通知函数
successMessage(value = "执行成功") {
uni.showToast({
title: value,
icon: "success",
duration: 1.5 * 1000,
});
},

接下来简单编写一个界面,
界面将清晰的反映isInvalid与loading状态时对应的UI交互:
正常

小程序码过期

整体测试
模拟器测试
打开网页后,将图像另存为

在微信小程序调试工具,“通过二维码编译”

等待手机界面显示授权页面后点击“授权登录”:

GetCurrentUser接口返回正确数据,并显示于web页面之上

至此完成了小程序端的开发工作
项目地址
jevonsflash/abp-mp-auth (github.com)
结束语
小程序登录具有一定的扩展性,虽然通篇介绍微信小程序登录,但登录鉴权作为小程序抽象功能,uniapp集成了各个平台(微信、支付宝、百度、字节跳动小程序)的登录接口,通过uni.login可以获取相应平台的code
使用 Abp.Zero 搭建第三方登录模块(四):微信小程序开发的更多相关文章
- 使用 Abp.Zero 搭建第三方登录模块(一):原理篇
第三方登录是基于用户在第三方平台上(如微信,QQ, 百度)已有的账号来快速完成系统的登录.注册-登录等功能. 微信的鉴权 以微信的鉴权为例: 假如你的网站有一个扫码登录的功能,会弹出一个由微信提供的 ...
- 使用 Abp.Zero 搭建第三方登录模块(三):网页端开发
简短回顾一下网页端的流程,总的来说网页端的职责有三: 生成一个随机字符作为鉴权会话的临时Token, 生成一个小程序码, Token作为参数固化于小程序码当中 监控整个鉴权过程状态,一旦状态变为AU ...
- 微信小程序开发环境搭建
关注,QQ群,微信应用号社区 511389428 微信小程序可谓是今天最火的一个名词了,一经出现真是轰炸了整个开发人员,当然很多App开发人员有了一个担心,微信小程序的到来会不会给移动端App带来一个 ...
- 微信小程序开发系列一:微信小程序的申请和开发环境的搭建
我最近也刚刚开始微信小程序的开发,想把我自学的一些心得写出来分享给大家. 这是第一篇,从零开始学习微信小程序开发.主要是小程序的注册和开发环境的搭建. 首先我们要在下列网址申请一个属于自己的微信小程序 ...
- 微信小程序开发系列四:微信小程序之控制器的初始化逻辑
微信小程序开发系列教程 微信小程序开发系列一:微信小程序的申请和开发环境的搭建 微信小程序开发系列二:微信小程序的视图设计 微信小程序开发系列三:微信小程序的调试方法 这个教程的前两篇文章,介绍了如何 ...
- 微信小程序开发用户授权登录
用wx.login获取登录凭证code <!--pages/user/index.wxml--> <view hidden='{{boolean}}'> <view wx ...
- 微信小程序开发:python+sanic 实现小程序登录注册
开发微信小程序时,接入小程序的授权登录可以快速实现用户注册登录的步骤,是快速建立用户体系的重要一步.这篇文章将介绍 python + sanic + 微信小程序实现用户快速注册登录全栈方案. 微信小程 ...
- 微信小程序开发(四)线程架构和开发步骤
线程架构 从前面的章节我们可以知道,.js文件是页面逻辑处理层.我们可以按需在app.js和page.js中添加程序在生命周期的每个阶段相应的事件.如在页面的onLoad时进行数据的下载,onShow ...
- 微信小程序开发教程(四)线程架构与开发步骤
线程架构 从前面的章节我们可以知道,.js文件是页面逻辑处理层.我们可以按需在app.js和page.js中添加程序在生命周期的每个阶段相应的事件.如在页面的onLoad时进行数据的下载,onShow ...
- 搭建微信小程序开发环境
1.下载开发工具 点击进入下载地址选择和自己电脑匹配的安装包,并安装: image.png 安装完成后出现应用icon: image.png 2.创建项目 能够扫码登录的前提是微信号已经注册了小程序, ...
随机推荐
- JVM(Java虚拟机) 整理
JVM整体结构 本文主要说的是HotSpot虚拟机, JVM 全称是 Java Virtual Machine,中文译名:Java虚拟机 简化一下: Java字节码文件 Class文件本质上是一个以8 ...
- 全新Self-RAG框架亮相,自适应检索增强助力超越ChatGPT与Llama2,提升事实性与引用准确性
全新Self-RAG框架亮相,自适应检索增强助力超越ChatGPT与Llama2,提升事实性与引用准确性 1. 基本思想 大型语言模型(LLMs)具有出色的能力,但由于完全依赖其内部的参数化知识,它们 ...
- 3.3 DLL注入:突破会话0强力注入
Session是Windows系统的一个安全特性,该特性引入了针对用户体验提高的安全机制,即拆分Session 0和用户会话,这种拆分Session 0和Session 1的机制对于提高安全性非常有用 ...
- 1.14 手工插入ShellCode反弹
PE格式是 Windows下最常用的可执行文件格式,理解PE文件格式不仅可以了解操作系统的加载流程,还可以更好的理解操作系统对进程和内存相关的管理知识,而有些技术必须建立在了解PE文件格式的基础上,如 ...
- PE格式:新建节并插入代码
经过了前一章的学习相信你已经能够独立完成FOA与VA之间的互转了,接下来我们将实现在程序中插入新节区,并向新节区内插入一段能够反向连接的ShellCode代码,并保证插入后门的程序依旧能够正常运行不被 ...
- 万字剖析OpenFeign整合Ribbon实现负载均衡的原理
大家好,前面我已经剖析了OpenFeign的动态代理生成原理和Ribbon的运行原理,这篇文章来继续剖析SpringCloud组件原理,来看一看OpenFeign是如何基于Ribbon来实现负载均衡的 ...
- .NET Core开发实战(第19课:日志作用域:解决不同请求之间的日志干扰)--学习笔记
19 | 日志作用域:解决不同请求之间的日志干扰 开始之前先看一下上一节的代码 // 配置的框架 var configBuilder = new ConfigurationBuilder(); con ...
- Python内置小工具(非常实用!)
一.1秒钟启动一个下载服务器在工作中时不时会有这样的一个需求:将服务器(或者自己电脑)上的文件传给其他同事.将文件传给同事本身并不是一个很繁琐的工作,现在的聊天工具一般都支持文件传输.但是,如果需要传 ...
- 【SpringBootStarter】自定义全局加解密组件
[SpringBootStarter] 目的 了解SpringBoot Starter相关概念以及开发流程 实现自定义SpringBoot Starter(全局加解密) 了解测试流程 优化 最终引用的 ...
- NC19872 [AHOI2005]SHUFFLE 洗牌
题目链接 题目 题目描述 为了表彰小联为Samuel星球的探险所做出的贡献,小联被邀请参加Samuel星球近距离载人探险活动. 由于Samuel星球相当遥远,科学家们要在飞船中度过相当长的一段时间,小 ...