image.png

按照纵轴划分,包含了小程序API,开发者服务器,微信接口服务器。囊括的讲就是前端,后端,后端找微信端,这样的过程。
总结图片的核心知识点:

  1. 小程序调用wx.login()获取临时登录凭证code
  2. 小程序将code传到开发者服务器。
  3. 开发者服务器以code换取用户唯一标识openid和会话密钥session_key
  4. 开发者服务器可绑定微信用户身份id和业务用户身份。
  5. 开发者服务器可以根据用户标识来生成自定义登录态,用于后续业务逻辑中前后端交互时识别用户身份。
  6. 小程序调用wx.checkSession来检验session_key是否过期。

image.png

上面的登录时序中,我们会涉及到一些数据和参数,先来了解下它们都是用来做啥的。

临时登录凭证 code

在小程序中调用wx.login(),能拿到一个code作为用户登录凭证(有效期五分钟)。在开发者服务器后台,开发者可使用code换取openidsession_key等信息(code只能使用一次)。code的设计,主要用于防止黑客使用穷举等方式把业务侧个人信息数据全拉走。

AppId 与 AppSecret

为了确保拿code过来换取身份信息的人就是对应的小程序开发者,到微信服务器的请求要同时带上AppIdAppSecret

session_key

会话密钥session_key是对用户数据进行加密签名的密钥。为了应用自身的数据安全,开发者服务器不应该把会话密钥下发到小程序,也不应该对外提供这个密钥。
设计session_key主要是为了节省流程消耗,如果每次都通过小程序前端wx.login()生成微信登录凭证code去微信服务器请求信息,步骤太多会造成整体耗时比较严重。
使用接口wx.checkSession()可以校验session_key是否有效。用户越频繁使用小程序,session_key有效期越长。session_key失效时,可以通过重新执行登录流程获取有效的session_key

getAccessToken

获取小程序全局唯一后台接口调用凭据(access_token)。调用绝大多数后台接口时都需使用 access_token,开发者需要进行妥善保存。

access_token的存储与更新

  1. access_token 的存储至少要保留 512 个字符空间;
  2. access_token 的有效期目前为 2 个小时,需定时刷新,重复获取将导致上次获取的 access_token 失效;
  3. 建议开发者使用中控服务器统一获取和刷新 access_token,其他业务逻辑服务器所使用的 access_token 均来自于该中控服务器,不应该各自去刷新,否则容易造成冲突,导致 access_token 覆盖而影响业务;
  4. access_token 的有效期通过返回的 expire_in 来传达,目前是7200秒之内的值,中控服务器需要根据这个有效时间提前去刷新。在刷新过程中,中控服务器可对外继续输出的老 access_token,此时公众平台后台会保证在5分钟内,新老 access_token 都可用,这保证了第三方业务的平滑过渡;
  5. access_token 的有效时间可能会在未来有调整,所以中控服务器不仅需要内部定时主动刷新,还需要提供被动刷新 access_token 的接口,这样便于业务服务器在API调用获知 access_token 已超时的情况下,可以触发 access_token 的刷新流程。

openid

openid是微信用户id,可以用这个id来区分不同的微信用户。
微信针对不同的用户在不同的应用下都有唯一的一个openid, 但是要想确定用户是不是同一个用户,就需要靠unionid来区分。

unionid机制说明

如果开发者拥有多个移动应用、网站应用、和公众帐号(包括小程序),可通过unionid来区分用户的唯一性。同一用户,对同一个微信开放平台下的不同应用,unionid是相同的。

unionid获取途径

绑定了开发者帐号的小程序,可以通过以下途径获取 UnionID。

  1. 调用接口 wx.getUserInfo,从解密数据中获取 UnionID。注意本接口需要用户授权,请开发者妥善处理用户拒绝授权后的情况。
  2. 如果开发者帐号下存在同主体的公众号,并且该用户已经关注了该公众号。开发者可以直接通过 wx.login + code2Session 获取到该用户 UnionID,无须用户再次授权。
  3. 如果开发者帐号下存在同主体的公众号或移动应用,并且该用户已经授权登录过该公众号或移动应用。开发者也可以直接通过 wx.login + code2Session 获取到该用户 UnionID ,无须用户再次授权。
  4. 用户在小程序(暂不支持小游戏)中支付完成后,开发者可以直接通过getPaidUnionId接口获取该用户的 UnionID,无需用户授权。注意:本接口仅在用户支付完成后的5分钟内有效,请开发者妥善处理。
  5. 小程序端调用云函数时,如果开发者帐号下存在同主体的公众号,并且该用户已经关注了该公众号,可在云函数中通过 cloud.getWXContext 获取 UnionID。
  6. 小程序端调用云函数时,如果开发者帐号下存在同主体的公众号或移动应用,并且该用户已经授权登录过该公众号或移动应用,也可在云函数中通过 cloud.getWXContext获取 UnionID。

    代码演示

    ```javascript const COMMONWXLOGIN = (callback) => { wx.login({
    1. success: function (res) {
    2. if (res.code) {
    3. PROMISE('member/code2session', { 'code': res.code, 'hotelId': HOTELID}).then((res) => {
    4. wx.setStorageSync('user', res);
    5. typeof callback == 'function' && callback(res);
    6. }, (err) => {
    7. typeof callback == 'function' && callback(err);
    8. })
    9. }
    10. else {
    11. typeof callback == 'function' && callback(res);
    12. }
    13. },
    14. fail: function (err) {
    15. // console.log(`登录失败`);
    16. typeof callback == 'function' && callback(err);
    17. }
    }) }

const WXLOGIN = (callback) => { wx.checkSession({ success: function() { //session_key 未过期,并且在本生命周期一直有效 if (wx.getStorageSync(‘user’)) { typeof callback == ‘function’ && callback(wx.getStorageSync(‘user’)); } else { COMMONWXLOGIN(callback); } }, fail: function() { //session_key 已经失效,需要重新执行登录流程 COMMONWXLOGIN(callback); } }) } ```

wx.checkSession

检查登录态是否过期。
通过 wx.login接口获得的用户登录态拥有一定的时效性。用户越久未使用小程序,用户登录态越有可能失效。反之如果用户一直在使用小程序,则用户登录态一直保持有效。具体时效逻辑由微信维护,对开发者透明。开发者只需要调用 wx.checkSession 接口检测当前用户登录态是否有效。
登录态过期后开发者可以再调用 wx.login 获取新的用户登录态。调用成功说明当前 session_key 未过期,调用失败说明 session_key 已过期。