代码地址22510/BlockChainBlog: 区块链工作室网站 (github.com)
小程序登录流程
在微信小程序的开放文档开放能力 / 用户信息 / 小程序登录 (qq.com)中就给出了小程序的登录时序图, 我们就可以基于这个图去构建我们自己的登录认证体系.
从上面的流程图, 我们可以得知要进行微信小程序, 涉及三步:
- 在进入小程序时,
wx.login
函数可以发送一个code - 后端接收code并结合小程序的appid+appsecret调用微信的API进行认证
- 经过微信API认证, 通过认证会返回用户的openid和session_key, 而openid是每一个微信小程序下每一个微信用户各自独有, 可以作为我们用于标识一个用户的参数
当后端拿到openid时, 其实就算作用户通过了小程序的认证.
但由于我们的小程序通常要服务于其他网页, 小程序只是一个辅助登录浏览信息的作用, 所以还需要对登录进行定制化操作.
openid绑定邮箱
数据库设计
本次小程序登录关联的是之前已有的工作室网站项目, 而那那个项目依靠的是邮箱+密码登录, 所以需要将用户的openid和邮箱建立关系.
这里涉及到的问题是第三方统一登录
, 推荐几篇文章: 公司用了 3 年多的多账号统一登录方案,万能通用,稳的一批! (qq.com), 浅谈第三方登录用户表结构设计方案 - 知乎 (zhihu.com). 这里我选择的方案是: 原来的用户表(user, 邮箱+密码登录)不变, 新建一个第三方认证表(userauth, 参数为openid+sessionkey)关联user表的用户id
. 这样设计的好处是不用修改原来的代码.
梳理登录流程
画了个简单的流程图, 方便理解.
讲解一些细节的点:
wx.login
在进入login
页面触发, 由于wx.request
的请求是异步的(这里我封装wx.request
为request.js
), 所以需要一顶等待时间来获取后端的返回结果, 所以设置了一个“加载中”的动画阻止用户点击“立即登录”- 如果用户之前认证过, 后端会返回
success为true
, 并携带token
, 当用户点击立即登录时, 检测到本地有token, 就放行 - 如果用户之前未认证过, 后端会返回
success为false
, 并携带auth
,auth
用于获取openid
(openid不能发送共前端, 我们只能想办法自己暂存, 之后邮箱绑定要用到), 当用户点击立即登录时, 检测到无token
, 跳转到绑定邮箱页面.
- 如果用户之前认证过, 后端会返回
- 在进行邮箱绑定时, 要将用户的
openid
和邮箱
关联起来, 但如前面所说,openid
最好不要发送给后端, 所以我们只能自己想办法暂存openid
- 一开始我想到的方案是: 用
ThreadLocal
. 用户进入小程序时, 调用wx.login
访问后端, 后端对应接口在检测到用户未绑定邮箱时, 将openid
暂存到ThreadLocal
. 当用户进行绑定时, 就可以拿出ThreadLocal
中的openid
, 完成绑定操作. 但我发现这两个操作的请求会被分配到不同线程, 导致绑定时拿不到openid, 所以失败了. - 然后就是常用的
Redis
方案:wx.login
访问后端, 检测到未绑定, 生成一个auth
作为Redis
的key
,openid
为值, 将auth
返回给后端. 绑定操作时携带auth
就能从Redis
中拿到openid
, 从而完成绑定
- 一开始我想到的方案是: 用
具体代码实现
小程序代码
借鉴了一下微信小程序登录注册界面_微信小程序注册页面-CSDN博客的代码, 写得很好啊.
上面基本讲解得差不多了, 没啥难点, 只要把思路捋清楚就很好弄.
后端代码
Controller层
两个接口:
wxLogin
: 对应小程序的wx.login
中的请求, 用于用户登录wxLink
: 对应小程序的wxEmailLink
中的请求, 用于用户邮箱绑定
Service层
都是比较基础的操作