微信小程序扫码实现web自动登录
清明假期在家无聊,写了一个微信小程序扫码,web登录的demo
技术栈
前端:vue2+vue-socket.io+uuid,微信小程序原生+weapp.socket.io
后端: eggjs+redis+socket.io+qr-image
细分说明
web端流程
- 打开登录页面
- 请求获取二维码
- 客户端先生成一个唯一值uuid, 携带uuid请求服务端,服务端并将uuid作为key,值为空,一个过期时间,存进redis中
- 服务端利用uuid,作为qr-image的option,生成二维码(微信小程序扫码,获取的值就是uuid)
- 浏览器可拿到二维码和uuid,vue-socket.io长连接监听uuid,是否绑定accessToken。如果有绑定值,调用获取用户信息的接口,web端成功登录;若在redis的过期时间内取不到,就说明二维码失效,重新刷新二维码。
微信小程序扫码流程
- 注册/登录账号成功,生成accessToken。打开扫一扫,扫描web二维码
- 扫描二维码后得到uuid
- 确认按钮点击,socket将accessToken和uuid传递给服务端
- 服务端验证accessToken和uuid,满足条件socket通知微信小程序最终确认授权
- 微信小程序确认授权后,socket传递uuid和accessToken给web端。web端获取到accessToken,再走获取用户信息的接口。就达到web扫码登录的功能了。
大致的扫码流程就是如此。我呢做了一个基础版本。扫码,微信小程序redis绑定uuid和accessToken,再派发给web端,没有添加校验。
核心代码块
后端
获取二维码
const qr = require("qr-image");/*** @summary 获取二维码* @description 获取二维码* @router get /api/v1/user/generateQrCode* @request query integer size 大小 默认 1* @request query integer margin 二维码周围间距默认1* @request query string uuid 唯一标识* @response 200 baseResponse successed*/async generateQrCode() {const { ctx, service } = this;const { size, margin, uuid } = ctx.query;try {// 大小默认5,二维码周围间距默认1const img = qr.image(uuid || "", {type: "png",size: size || 5,margin: margin || 1,});ctx.status = 200;const result = {img,type: "image/png",};await service.redis.set(uuid, "", 300); ctx.body = img// ctx.body = ctx.helper.response({ data: result, msg: "生成成功" }); // 不能获取img对象赋值,直接src渲染} catch (e) {ctx.status = 414;ctx.set("Content-Type", "text/html");ctx.body = "<h1>ERROR</h1>";}}
}
<img src="xxxx//api/v1/user/generateQrCode?uuid=xxx" />
egg 开启socket.io
官网链接
安装
$ npm i egg-socket.io --save
开启插件
// {app_root}/config/plugin.js
exports.io = {enable: true,package: 'egg-socket.io',
};
配置
// {app_root}/config/config.${env}.js
exports.io = {init: { }, // passed to engine.ionamespace: {'/': { // connectionMiddleware是在client保持连接的时候调用的中间件connectionMiddleware: [],// packetMiddleware是在server发送包给client之后调用的中间件packetMiddleware: [],},'/example': {connectionMiddleware: [],packetMiddleware: [],},},
};
socket.io规定文件夹
demo
├── app
│ ├── extend
│ │ └── helper.js
│ ├── io
│ │ ├── controller
│ │ │ └── default.js
│ │ └── middleware
│ │ ├── connection.js
│ │ └── packet.js
│ └── router.js
├── config
└── package.json
比如命名空间 " / "需要用到中间件 connection
// {app_root}/config/config.${env}.js
exports.io = {init: { }, // passed to engine.ionamespace: {'/': { // connectionMiddleware是在client保持连接的时候调用的中间件connectionMiddleware: ['connection'],// packetMiddleware是在server发送包给client之后调用的中间件packetMiddleware: [],},},
};
connection.js
const room = "default_room";module.exports = () => {return async (ctx, next) => {// 权限校验通过ctx.socket.emit("res", "auth success");// 加入房间ctx.socket.join(room);ctx.socket.emit("dataState", {a: 3,}); // 测试ctx.socket.on("checkQrCodeAndSaveAccessToken", async (data) => { // 绑定 uuid : accessToken 键值if (data.qrCode) {const exist = await ctx.service.redis.isExistKey(data.qrCode);if (exist) {await ctx.service.redis.set(data.qrCode, data.accessToken, 60);} else {ctx.socket.emit("qrCodeStatusFromRedis", { status: 0 });}}});ctx.socket.on("sendQrCodeForAccessToken", async (data) => { // 小程序确认,向web端派发accessTokenif (data.qrCode) {const exist = await ctx.service.redis.isExistKey(data.qrCode);if (exist) {const accessToken = await ctx.service.redis.get(data.qrCode);ctx.socket.emit("sendAccessToken", { accessToken });} else {ctx.socket.emit("qrCodeStatusFromRedis", { status: 0 });}}});// 放行await next();console.log("断开连接");};
};
socket.io router-controller (扩展)
为了分离,方便维护代码
// {app_root}/app/router.js
module.exports = app => {const { router, controller, io } = app;router.get('/', controller.home.index);// socket.io // 可以说成监听命名空间为"/" 上 exchange方法io.of('/').route('exchange', io.controller.nsp.exchange);
};
客户端只需要
socket.emit('exchange', {});
框架是以 Cluster 方式启动的,而 socket.io 协议实现需要 sticky 特性支持,否则在多进程模式下无法正常工作。
由于 socket.io 的设计,在多进程中服务器必须在 sticky 模式下工作,故需要给 startCluster 传递 sticky 参数。
修改 package.json 中 npm scripts 脚本:
{"scripts": {"dev": "egg-bin dev --sticky","start": "egg-scripts start --sticky"}
}
前端
微信小程序
npm i weapp.socket.io// 小程序端示例代码
const io = require('weapp.socket.io')const socket = io('http://localhost:8005', {transports: ['websocket'],extraHeaders: {token: wx.getStorageSync('token'), // 在这里扩展,header增加了token,socket校验,为了严谨。此处token跟二维码token无关},reconnectionAttempts: 3, // 失败后重新连接次数,一直失败总共尝试四次reconnectionDelay: 2000, // 重新连接间隔时间毫秒forceNew: true,
})socket.on('connect', function () {console.log('connected')
});page({openscanCode() { // 扫一扫事件const that = thiswx.scanCode({success(res) {if (res.errMsg === 'scanCode:ok') {const data = res.resultthat.setData({qrCode: data})socket.emit("checkQrCodeAndSaveAccessToken", {qrCode: data,accessToken: 'access_token' // 做测试})}}})},
})
web
npm i vue-socket.io
注册
main.js
import VueSocketIO from 'vue-socket.io'Vue.use(new VueSocketIO({debug: true,connection: 'http://127.0.0.1:8005/',
}))
页面
<template><div id="app"><div><img alt="Vue logo" :src="url"></div></div>
</template><script>
import { v4 as uuidv4 } from 'uuid';
import HelloWorld from './components/HelloWorld.vue'export default {name: 'App',data:{url: 'http://127.0.0.1:8005/api/v1/user/generateQrCode?uuid=' + uuidv4()}components: {HelloWorld},sockets: {connect() {console.log('链接成功');},dataState2: (data) => {console.log(data,'data')},disconnect() {console.log('断开链接')},reconnect() {console.log('重新链接')},sendAccessToken(res) {console.log('VueSocketIO', res.accessToken) // 调用用户信息接口}},mounted() {console.log(this)// this.$socket.emit('chat', { subscribe: true }) // 事件派发}
}
</script><style>
#app {font-family: Avenir, Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;text-align: center;color: #2c3e50;margin-top: 60px;
}
</style>
就这样基础版本的微信小程序扫码,web自动登录完成
微信小程序扫码实现web自动登录相关推荐
- 微信小程序扫码报工案例分享
使用微信小程序结合PC端ERP完成工序扫码报工+扫码出入库,可以实现生产管理全流程自动化作业,使生产效率比之前手工操作有了质的飞跃. 本案例背景介绍 这是一家生产二极管的电子生产企业,车间自动化生产设 ...
- 表情包壁纸独立后台美化二开版本新增加神器功能微信小程序源码下载+教程自动采集
相信玩小程序的朋友对这款小程序应该也不陌生 这是前半年很火的一款微信表情包小程序功能 之前的版本内置了表情包还有壁纸功能 这一期的版本给优化了一下UI和新增加了一些喝酒神器功能 具体新增加的喝酒神器功 ...
- 新款最火表情包壁纸独立后台美化二开版本新增加喝酒神器功能微信小程序源码下载+教程自动采集
相信玩小程序的朋友对这款小程序应该也不陌生 这是前半年很火的一款微信表情包小程序功能 之前的版本内置了表情包还有壁纸功能 这一期的版本给优化了一下UI和新增加了一些喝酒神器功能 具体新增加的喝酒神器功 ...
- 3-STM32+Air724UG基本控制篇(自建物联网平台)-整体运行测试-微信小程序扫码绑定Air724,并通过MQTT和模组实现远程通信控制
说明 这节测试一下微信小程序扫码绑定Air724模组然后实现微信小程序和开发板之间通过MQTT进行远程通信控制. 这一节作为板子的整体功能测试,用户下载这一节的程序用来测试基本控制篇实现的基本功能 还 ...
- 小程序源码:最新掌上题库微信小程序源码下载,修复登录接口,支持在线考试,自定义导入考题-多玩法安装简单
这是一款题库微信小程序源码 支持积分商城.自定义试题及导入.知识点分类.模式试题考试.流量主等 首页模块:专项刷题 .题型刷题.乱序刷题.我的收藏.我的错题.未作习题.刷知识点.考前必背 另外还有更多 ...
- 最新掌上题库微信小程序源码下载,修复登录接口,支持在线考试,自定义导入考题
这是一款题库微信小程序源码 支持积分商城.自定义试题及导入.知识点分类.模式试题考试等 首页模块:专项刷题.题型刷题.乱序刷题.我的收藏.我的错题.未作习题.刷知识点.考前必背 另外还有更多功能就不一 ...
- 使用微信小程序扫码登录系统PC端web的功能
1.项目说明: 项目PC端(vue单页面应用,前后端分离).移动端(微信小程序)共用同一Java Springboot服务.小程序可以直接获取微信手机号登录,不需要密码,因为系统黙认密码是随机的,因此 ...
- web端接入微信小程序扫码进行登录
1.拿到小程序的appid和secret 2.调用微信生成小程序的接口getUnlimitedQRCode(没有数量限制,调用详情请看api文档,这里仔细一点access_token是在url后面的, ...
- 基于SSM框架的微信小程序扫码点餐
随着我国经济迅速发展,人们对网络管理的需求越来越大,各种系统也越来越多,由于微信的发展,微信的功能越来越齐全,越来越多的人开始使用微信.因此,特开发了本微信小程序--基于微信小程序的扫码点餐小程序的设 ...
最新文章
- Feflow 源码解读
- python常用知识点_Python常用知识点
- mysql查询_MySQL基础,查询语句详解
- 英语听力里面的religion words
- 计算机工具软件应用考试,《计算机常用工具软件》期中考试题
- 详尽kmp_详尽的分步指南,用于数据准备
- js计算浮点数出现小数;解决js计算小数问题;js数组相加出现小数;
- leetcode 18 --- 4sum
- 考察数据科学家支持向量机(SVM)知识的25道题,快来测测吧
- python-opencv学习笔记(三)
- Java三大框架之——Hibernate关联映射与级联操作
- STM32 - 定时器高级应用说明 - 多触波的实现 (N-pulse waveform generation using timer synchronization)- 02
- mysql client version_下载mysqlclient问题报错
- 光刻机的“崛起秘密”,第一本ASML的企业成长传记来了!
- 《机器人编程实战》一一1.2 给机器人指令
- 【java笔记】继承
- RAC 特点 character
- java多线程同步与测试_Java多线程同步Synchronized深入解析
- MyBatisPuls入门案例
- linux wifi6,WIFI6 基本知识(一)
热门文章
- 「溪数科技」获逾5千万天使轮融资,开启智能运维加速模式!
- 2020 华数杯——脱贫帮扶绩效评价(Python代码实现)
- VMWare 15安装以及创建Ubuntu虚拟机
- 在线研讨会 matlab,MatLab
- 3D动作绑定_三维动画制作流程——商迪3D科普分享系列(二)
- 已解决(Python读取xml文件报错)xmL.etree.ELementTree.ParseError:not well-formed (invalid token): Line
- Windows系统win10系统日历日程管理软件推荐
- Qt QIODevice::Unbuffered 理解
- 苹果笔记本显卡性能测试软件,苹果新MBP性能测试成绩出炉:SSD表现出色 显卡性能偏弱...
- 25岁德邦被京东收购,网友:这次。。。