概述
当你开发完了一个小程序并部署上线后, 某个微信用户第一次访问这个小程序的时候, 会弹出一个授权界面, 用户可以选择是否使用微信登录, 如果选择是, 则直接进入到小程序当你第二次进入该小程序的时候, 你会发现授权界面不会弹出来了, 直接就进入小程序了
这个过程看起来非常的简单, 但其实实现起来相当的麻烦和繁琐涉及到会话安全验证等各种各样的问题下面笔者介绍一下实现这个登录过程的思路
微信提供小程序登录流程图
我们可以从登录流程时序 找到这张图想完全看懂张图, 需要了解很多东西我们先来看看微信提供的几个接口
小程序接口介绍
wx.login()
这个方法是小程序端发起的, 如果是使用腾讯团队推出的小程序组件化开发框架的 wepy 的话, 伪代码如下:
- wepy.login()
- .then(res => {
- const code = res.code
- })
这样子就可以从微信平台获取一个 code, 这个 code 是临时登录凭证, 用于获取 openid 的
wx.request()
这个也是小程序端发起的, 用于请求开发者服务器 (也即是我们的应用服务器) 上的接口, 调用的伪代码如下:
- wepy.request({
- url: `xxurl`,
- data: {
- // 入参
- },
- })
- .then(res => {
- // 从 res 中获取应用服务器返回的数据
- })
获取 openid 的接口
当某个开发主体开发了一个小程序后, 当用户访问这个小程序的时候, 微信平台会为这个用户分配一个 openid 如下接口:
https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code
这个微信接口一般是我们的应用服务器发起调用的, 而不是小程序端发起的
wx.getUserInfo
getUserInfo 这个接口用于在微信平台获取用户信息注意, 如果微信用户第一次访问小程序, 是弹出一个授权界面的当用户授权后, getUserInfo 才能调用并返回用户数据
这个四个接口在使用微信访问小程序的时候都会用到的
基于 token 保持会话和登录认证
小程序虽然不支持 cookie 的机制, 但是支持在 header 里设置 token
这个 token 是应用服务器生成的
- header: {
- 'xxxxtoken': token,
- }
当小程序调用应用服务器接口的时候, 必须带上这个 token, 应用服务端则对这个 token 进行解析和认证
当然如果是第一次访问小程序, 只能由应用服务器先生成 token
笔者打算用伪代码来表达使用 token 后, 整个登录的过程, 因为用文字或者图比较难表达
- const code = wx.login();
- if (code ) {//code 存在
- // 从小程序的本地中获取 toten
- const token = wx.getStorageSync('xxxxxtoken')
- if (token ) {// 小程序本地存有 token, 无需弹出授权界面
- // 直接传入 code 字段, 调用应用服务器的验证 token 的方法, 如果校验成功, 需要返回用户信息
- const userinfo = wx.request(http://xxxxxValidateToken(code ));
- if (userinfo) {
- // 说明登录成功, 直接进入小程序的主界面
- }
- }
- else {
- // 说明小程序本地没有 token, 这个时候需要弹出授权界面, 让微信用户决定是否访问小程序, 如果用户选择是的话
- const weixinuserinfo = wx.getUserInfo();// 会弹出授权界面, 微信提供的
- if (weixinuserinfo ){
- // 生成或者验证 token
- const userinfo = wx.request(http://xxxxxValidateToken(code ));
- const token = userinfo.getToken();
- // 将 token 存储到小程序本地
- wx.setStorageSync('xxxxxtoken', token )
- }
- }
- }
上面的伪代码中, 会调用应用服务器 (我们的应用服务器) 的
http://xxxxxValidateToken(code )
方法这个方法的实现逻辑大概如下:
1 先验证这个微信用户是否存在, 可以调用微信提供的 jscode2session 方法, 该方法会返回一个 openid 我们必须在业务代码里, 将这个 openid 保存到数据库, 并和 userid 关联起来
2 判断是否是新的用户, 如果是, 则生成 token 和生成新的一个用户信息存储到数据库如果不是新的用户, 则验证 token
这个流程走完后, 小程序就可以通过 wx.request 方法, 带上 token, 真正的访问应用服务器的业务方法, 获取业务数据
token 的生成和校验
见过有些公司是直接将 userid 和 openid, 加密后返回给小程序也见过用 userid 和 password 加密后返回给小程序如果是选择第二种方式的话, 验证 token 的逻辑大概如下:
先解密, 获取 userid 和 password, 并根据 userid 从数据库中获取到用户密码, 跟从 token 中解密出来的 password 进行比对, 如果相等, 则校验通过
总结
现在再回头看看微信提供登录路程图, 是否好理解一些了
来源: https://blog.csdn.net/linsongbin1/article/details/79673537