View on GitHub

Yinjie - GitHub.io

Welcome to the Yinjie's notes

微信小程序用户登录(微信+自己业务)方案

新历年开始,受公司大 BOSS 提出的 “节后上线100个小程序” 的号召🙄,就一直在搞小程序。绝大多数是工具类型的,但“很巧”的是,我接到的项目都是和用户身份强关联的需求,不仅要登录微信方,还要和自己公司用户系统关联。 这就导致所有业务功能的前置条件就是合理实现接口登录态,下面就笔者的经历和方案,给大家分享一下。

背景

微信小程序虽说本质上是 h5,但运行模式是一个 app,没有什么 cookie 可操作,无法作为常规 web 的“后台写入 cookie”式的登录。 这个时候就需要像 app 一样,调用登录接口后,记录一个登录状态码(此文中,登录状态码变量假设为 login_string),以后每次访问后台接口都传递此参数,将 http request 从无状态变成“有状态”。

微信小程序本身就定有一套略复杂的登录方案(这里说一下腾讯系的产品,用户信息安全一直做非常严格,不惜用繁杂过程去换安全),文档很完备:

https://mp.weixin.qq.com/debug/wxadoc/dev/api/api-login.html#wxloginobject

三方的登录流程

整个登录过程需要三方配合实现,以下是简单的时序图:

/img/wx_mini/1.png

看起来并不是很简单,其中自己业务的登录我在这里还省去的,不过流程倒是挺清楚的。 后台部分先不多说,前端整个过程的每一步(绿色椭圆型框)都是异步过程,但是有先后顺序,需要注意回调的处理,这个对稍成熟的前端开发者也不是什么难事。

前端按需登录问题

从上图看,前端登录也很简单,就是三个步骤,一步套一步的获取就行。但是实际应用中,有以一几个问题:

  • 整个登录过程是异步的,每个页面的接口请求也是独立、异步的,也可能同一时刻是多个的,无法保证登录接口执行完再去调用业务接口
  • 如果每个页面都做自己的登录操作,再调用业务接口,登录态是保证了,但代码维护性太差了
  • getUserInfo、getLoginString 虽有先后顺序,但也需要作为一个独立接口被调用

总之,我们需要解决的是几个有上下文关系的异步接口的独立性问题,对业务接口调用来说应该是纯粹、透明的,不应该掺杂和登录相关的一切内容。

技术实现

问题实际涉及面不是很大,就是有点乱,所以这个时候就需要我们先要想清楚再做,这个很重要。

  • 对微信的 wx 作一层封装,内置登录的所有步骤,保证 wx.request 业务接口的纯粹、透明,最重要是已登录态,我们自己写一个 wx.req 方法
  • 分成 getUserinfo、getLoginString 两个核心方法,单例模式,不能重复获取
  • 保证多个业务接口同时调用时,登录过程的唯一性。

按照上面的的几个条件,大致的流程图如下:

/img/wx_mini/2.png

按上述实现过程,就可以解决接口调用时需要前置登录态的问题。

  • 其中淡蓝色的部分都是异步过程,笔者第一版是用常规的回调完成的,后来引入一个 promise 库,看起来更方便一些。
  • 有一处是类似队列的条件等待,笔者是用短轮询的方式解决的,如果有更好的方法可以留言。
  • 只有在第一次调用接口时才会启动整个过程,作到“按需登录”。在小程序体验上的好处就是,需要时才会弹出“是否授权”的选择提示框。

相关代码就不贴出来了,有了思路实现起来就快了。 最后,推广一下本人开发(前、后、部署)的小程序:“一起干干干”,大家可以去搜来用一用,简单小巧实用哦~~
“一起干干干”
“一起干干干”
“一起干干干”
说三遍🎱