小程序 登录 设计 第1篇
前端调用 是不需要进行任何相关操作的,所以触发登录完全是由前端去决定的,而进行登录不能以指定页面作为参考点,需要考虑到用户分享从其他页面进入的情况
现在需要一种,目前个人思考出有两种方案:
每个页面都套用一个 layout
自定义组件,在该组件的生命周期进行登录触发,然后触发完毕后在组件抛出一个登录后的回调函数,接着页面接收这个回调函数然后在这个函数调用业务 api
在每次请求服务端 api
之前,先进行登录,等待登录处理完毕之后再进行请求服务端
两者比较之后目前是采用第二种方式去进行登录流程设计,因为静默登录完全跟用户没有任何关系,只是单纯与服务端进行交流,所以不应该与页面有关系,应该是跟请求服务端 api
有关系
小程序 登录 设计 第2篇
微信官方提供的登录方案,总结为三步:
前端通过 () 获取一次性加密凭证 code,交给后端。
后端把这个 code 传输给微信服务器端,换取用户唯一标识 openId 和授权凭证 session_key。(用于后续服务器端和微信服务器的特殊 API 调用,具体看:微信官方文档-服务端获取开放数据)。
后端把从微信服务器获取到的用户凭证与自行生成的登录态凭证(token),传输给前端。前端保存起来,下次请求的时候带给后端,就能识别哪个用户。
如果只是实现这个流程的话,挺简单的。
但要实现一个健壮的登录过程,还需要注意更多的边界情况:
收拢 () 的调用:
由于 () 会产生不可预测的副作用,例如会可能导致session_key失效,从而导致后续的授权解密场景中的失败。我们这里可以提供一个像 () 的方法,掌握 () 控制权,对其做一系列的封装和容错处理。
调用的时机:
通常我们会在应用启动的时候( () ),去发起静默登录。但这里会由小程序生命周期设计问题而导致的一个异步问题:加载页面的时候,去调用一个需要登录态的后端 API 的时候,前面异步的静态登录过程有可能还没有完成,从而导致请求失败。
当然也可以在第一个需要登录态的接口调用的时候以异步阻塞的方式发起登录调用,这个需要结合良好设计的接口层。
以上讲到的两种场景的详细设计思路下文会讲到。
并发调用的问题:
在业务场景中,难免会出现多处代码需要触发登录,如果遇到极端情况,这多处代码同时间发起调用。那就会造成短时间多次发起登录过程,尽管之前的请求还没有完成。针对这种情况,我们可以以第一个调用为阻塞,后续调用等待结果,就像精子和卵子结合的过程。
未过期调用的问题:
如果我们的登录态未过期,完全可以正常使用的,默认情况就不需再去发起登录过程了。这时候我们可以默认情况下先去检查登录态是否可用,不能用,我们再发起请求。然后还可以提供一个类似 ({ force: true })的参数去强行发起登录。
1. 应用启动的时候调用
因为大部分情况都需要依赖登录态,我们会很自然而然的想到把这个调用的时机放到应用启动的时候( () )来调用。
但是由于原生的小程序启动流程中, App,Page,Component 的生命周期钩子函数,都不支持异步阻塞。
那么我们很容易会遇到 发起的「登录过程」在 的时候还没有完成,我们就无法正确去做一些依赖登录态的操作。
针对这种情况,我们设计了一个状态机的工具:status
基于状态机,我们就可以编写这样的代码:
2. 在「第一个需要登录态接口」被调用的时候去发起登录
更进一步,我们会发现,需要登录态的更深层次的节点是在发起的「需要登录态的后端 API 」的时候。
那么我们可以在调用「需要登录态的后端 API」的时候再去发起「静默登录」,对于并发的场景,让其他请求等待一下就好了。
以 作为 () 封装的「网络请求层」,做一个简单的例子:
当自定义登录态过期的时候,后端需要返回特定的状态码,例如:AUTH_EXPIRED 、 AUTH_INVALID 等。
前端可以在「网络请求层」去监听所有请求的这个状态码,然后发起刷新登录态,再去重放失败的请求:
那么如果并发的发起多个请求,都返回了登录态失效的状态码,上述代码就会被执行多次。
我们需要对 () 做一些特殊的容错处理:
请求锁:同一时间,只允许一个正在过程中的网络请求。
等待队列:请求被锁定之后,调用该方法的所有调用,都推入一个队列中,等待网络请求完成之后共用返回结果。
熔断机制:如果短时间内多次调用,则停止响应一段时间,类似于 TCP 慢启动。
示例代码:
我们从上面的「静默登录」之后,微信服务器端会下发一个 session_key 给后端,而这个会在需要获取微信开放数据的时候会用到。
而 session_key 是有时效性的,以下摘自微信官方描述:
翻译成简单的两句话:
session_key 时效性由微信控制,开发者不可预测。
可能会导致 session_key 过期,可以在使用接口之前用 检查一下。
而对于第二点,我们通过实验发现,偶发性的在 session_key 已过期的情况下, 会概率性返回 true
社区也有相关的反馈未得到解决:
小程序解密手机号,隔一小段时间后,checksession:ok,但是解密失败
有效,但是解密数据失败
checkSession判断session_key未失效,但是解密手机号失败
所以结论是:可靠性是不达 100% 的。
基于以上,我们需要对 session_key 的过期做一些容错处理:
发起需要使用 session_key 的请求前,做一次 操作,如果失败了刷新登录态。
后端使用 session_key 解密开放数据失败之后,返回特定错误码(如:DECRYPT_WX_OPEN_DATA_FAIL),前端刷新登录态。
示例代码:
小程序 登录 设计 第3篇
作为一套可复用的小程序登录方案,当然需要去定义好前后端的交互协议。
那么整套登录流程下来,需要的接口有这么几个:
静默登录 silentLogin
后端利用 code 跟微信客户端换取用户标识,然后注册并登录用户,返回自定义登录态 token 给前端
token 前端会存起来,每个请求都会带上
userInfo 需要包含nickname和phone字段,前端用于计算当前用户的授权阶段。当然这个状态的记录可以放在后端,但是我们认为放在前端,会更加灵活。
token: 自定义登录态凭证
userInfo: 用户信息
code: 产自 ()
入参:
出参:
说明:
更新用户信息 updateUser
后端解密微信开放数据,获取隐蔽数据,如:unionId 等
后端支持更新包括 nickname等用户基本信息。
前端会把 userInfo 信息更新到 session 中,用于计算授权阶段。
userInfo:更新后的最新用户信息
nickname: 用户昵称
encrypt: 微信开放数据相关的 iv, encryptedData
以及其他如性别地址等非必要字段
入参:
出参:
说明:
更新用户手机号 updatePhone
后端解密开放式局,获取手机号,并更新到用户信息中。
前端会把 userInfo 信息更新到 session 中,用于计算授权阶段。
userInfo:更新后的最新用户信息
encrypt:微信开放数据相关的 iv, encryptedData
入参:
出参:
说明:
解绑手机号 unbindPhone
入参:-
出参:-
说明:后端解绑用户手机号,成功与否,走业务定义的前后端协议。
登录 logout
入参:-
出参:-
说明:后端主动过期登录态,成功与否,走业务定义的前后端协议。
最后我们来梳理一下整体的「登录服务」的架构图:
由「登录服务」和「底层建设」组合提供的通用服务,业务层只需要去根据产品需求,定制授权的流程 ,就能满足大部分场景了。
本篇文章通过一些常见的登录授权场景来展开来描述细节点。
整理了「登录」、「授权」的概念。
然后分别针对「登录」介绍了一些关键的技术实现:
静默登录
静默登录异步状态的处理
自定义登录态过期的容错处理
微信 session_key 过期的容错处理
而对于「授权」,会有设计UI部分的逻辑,还需要涉及到组件的拆分:
组件拆分与设计
权限拦截的处理
然后,梳理了这套登录授权方案所依赖的后端接口,和给出最简单的参考协议。
最后,站在「秉着沉淀一套通用的小程序登录方案和服务为目标」的角度,梳理了一下架构层面上的分层。
业务定制层
登录服务层
底层建设
以上就是微信小程序登录前端的设计与实现详解的详细内容!