最近发现小程序的登录逻辑还有一些新的心得,所以记录一下。
在小程序官网里面会提到一个小程序的登录逻辑,这是官方推荐的登录逻辑,也就是所谓的小程序登录态维护逻辑,这里是官方的图:
官方逻辑的个人理解:
wx.login
获取微信的 code,然后将这个 code 发送给开发者服务器(我们自己的开发服务器)。code2Session
这个api 接口来获取真正需要的微信用户的登录态session_key
和 openid
和 unionid
。session_key
才是真正的微信登录态信息,但是把 openid
和 unionid
加起来一起理解,也可以笼统地理解为这些都是微信的登录态信息。session_key
和 openid
和 unionid
),并且做关联处理,然后返回给小程序客户端。app.globaldata
,也可以是 localstoage
,注意,小程序不支持 cookie
。openid
或者 unionid
和 session_key
相匹配。code2Session
进行微信登录态更新。整个微信小程序官方推荐的登录态维护流程就是这样了,官方推荐使用自定义登录态来进行整个微信小程序的登录维护,既然寄人篱下,那么就要按部就班,跟着政策走,这是最好的应对。
上面的图里面的一些术语解释:
code
是微信用户的登录凭证,打开小程序登录的时候获取的只属于微信这个用户的登录凭证,需要注意的是,这个登录凭证只供微信小程序使用的。code
的存活时间一般是5分钟左右,这是一个临时的登录凭证,他的最大作用就是确定是来源自哪一个微信用户来打开,是为了后续生成一个微信登录态 session_key
而使用的。session_key
是微信用户在小程序里面的登录态信息,这是微信给这个用户颁发的一个登录 session
。{"session_key",openid":"..."}
,官方说需要定期使用wx.checkSession
检测,但是在实际的场景里面其实也可以不用,用和不用主要看你怎么设计你的微信小程序,这个后续会说。expire_time
过期时间的,但是后面取消了,这里有一个比较新的官方回复:用户越频繁使用小程序,session_key有效期越长,…… | 微信开放社区,有效期是3天,但是这个不一定是固定的,具体看业务需求,总的原则就是维护一个自定义登录态,自定义登录需要和微信登录态关联。openId
,用户在微信里面的唯一标识,但是需要跟 unionid
进行一起理解。unioinId
,如果开发者拥有多个移动应用、网站应用、和公众帐号(包括小程序),可通过unionid
来区分用户的唯一性,因为只要是同一个微信开放平台帐号下的移动应用、网站应用和公众帐号(包括小程序),用户的unionid
是唯一的。换句话说,同一用户,对同一个微信开放平台下的不同应用,unionid
是相同的。openId
就是微信用户的唯一标识,但是因为微信产品很多,所以会出现多个微信产品使用不同的 openId
来标识用户,但是对于我们做业务接入的话,就买办法使用了,所以建议是统一使用 unioinid
,因为一般来说,一般的业务都会有公众号,小程序联合使用的,所以 unionid
使用频率较高。3rd_session
是一般是指开发者服务器的登录态,也就是自定义登录态,也就是我们自己公司的业务服务器的登录态(微信官方推荐使用自定义登录态来管理整个微信小程序登录)。wx.checkSession
来检查,如果过期了,就本地执行登录操作,再让开发者服务器跟微信服务器交互,获取新的小程序登录态,然后关联到自定义登录态。session_key
作为代表理解。session
会话,官方说的3rd_session
就是这个。只有理解好官方的标准流程,才能更好地理解其他流程,或者其他人对官方流程的封装和注解!
上面是基本的登录流程理解,但是实际业务中还是会有一些地方需要补充的,但是我们理解的时候最好把他们分开,这样会更清晰和简单。
按照官方推荐的方式是使用自定义登录态来管理整个微信小程序登录流程的,虽然说是通过一个自定义登录态来管理,但是其实里面是有变通的。
这里有2种方式来做:
wx.checkSession
检查微信登录态是否过期:上面说的方式都是打开小程序的时候做的,但是也要考虑到一种情况,就是自定义登录态在用户使用小程序的过程中过期了,那么这时候也是需要强制执行完整的登录流程的。
相对来说方式二比较好,方式二的好处是不需要小程序服务端来参与校验,而是在小程序端调用API。这种方式实际上是将维护登录态的机制委托给了微信维护的session_key,开发者不需要在自定义的登录态中保存有效期信息。腾讯云开发的wafer项目便采取了这种方法。
上面提到的方式二是在打开小程序的时候做的,这里是在每次发起 HTTP 请求的时候做的,这个是不一样的逻辑。
当小程序客户端访问接口的时候,开发者服务器返回说你的自定义登录态过期了,你就需要重新发起完整的登录,但这里有2个点是需要注意的:
所以这里就需要进行封装一下,Random Notes这里就提到了,思路是正确的,不过实现的话可以按自己需要实现,他这里有2个地方描述得很好,所以我搬过来借鉴了。
这是一个宏观的,每个请求都要检查一下登录态的逻辑图:
图片引用自:https://blog.imtouch.info
每个请求都会检查一次登录态,不管是自定义登录态还是微信登录态,反正只要发起跟开发者服务器交互的 HTTP 请求的之前都会检查。
细分逻辑的话就会变成这样:
图片引用自:https://blog.imtouch.info
细分逻辑之后看起来会更加清晰,并且这里的逻辑是微信登录态和自定义登录态都会检查一遍,任何一个登录态过期都会发起完整的登录逻辑,其实我觉得这里也可以只判断自定义登录态的状态也可以的。
不过由此也带来一个问题,就是如果一个页面里面有多个请求同时发起的话,那么就会出现同时检查到登录态过期,然后同时发起登录的情况,这个问题可能会导致开发者服务器的校验登录数据出现问题,他这里用到 promise.race
来解决,具体可以看他的文章里面介绍,我后面也会继续写一下这个处理的介绍。
参考文档: