阅读 1251

小程序登录踩坑笔记

前言

最近因工作需求开发了两款小程序,在开发过程中登录流程一改再改,小程序文档的登录流程只是提供了参考,具体的流程设计还是需要和业务需求相结合,本文主要是一个前端小白在小程序登录流程的踩坑记录。

因为作者所在项目的实际业务需求,本文的登录流程主要和手机号授权结合考虑,且不考虑实现多个小程序、公众号公用一个登录体系的场景。

接入登录

1、官方文档的登录

直白的来看,wx.login()和之后的一切流程即是客户端告诉服务端当前登录的微信号是那个,并存储标识符openid和session_key,微信官方提供小程序授权的手机号可以任意切换的功能,所以一个微信号可以对应多个微信号。

2、手机号授权

微信提供的手机号授权方法必须用户主动触发才能发起获取手机号接口,所以该功能不由 API 来调用,需用 button 组件的点击来触发。

<button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber"></button>
复制代码

注意:客户端通过getPhoneNumber拿到的用户信息的敏感信息是微信接口服务通过当前微信号登录态的session_key生成的,所以服务端需要用对应的session_key才能解密出对应的用户信息。

实际开发过程

1、第一版流程

第一版流程设计的两个明显错误:

  • 登录态token存储在了globalData
  • wx.login和getPhoneNumber的调用顺序

globalData是内存,当手机关闭微信的后台运行时会清空内存,globaleData会被清空,登录态就失效了。第一次系统的写小程序,错误的认知globalData和storage的时效是一样的,所以犯了这么低级的错误,正确的做法是存储在storage里,官方文档给出storage的存储时效是:除非用户主动删除或因存储空间原因被系统清理,否则数据都一直可用。

<view class="author-btn-wrp" capture-bind:tap="handleClick">
    <button class="author-btn btn-class" open-type="getPhoneNumber" bindgetphonenumber="handleGetPhone">
      <image src="{{btnIcon}}" wx:if="{{btnIcon}}" />
      <text>{{btnText}}</text>
    </button>
  </view>
复制代码

初版上线的小程序,用户点击按钮,handleClick这个点击事件里面执行wx.login并在回调存储了code,open-type的开放能力执行了getPhoneNumber,在getphonenumber的回调函数handleGetPhone里面获得iv和encryptedData,从内存中获取code将三个参数传给服务端解析用户信息。
这个流程因为wx.login和getPhoneNumber的调用顺序无法控制,且两个过程都是异步的,如果getPhoneNumber调用在微信服务先生成iv和encryptedData,而后wx.login生成了新的登录态session_key返回code,这种时候拿到的code和iv、encryptedData不对应,是不能通过微信api解析出用户信息的。

2、第二版流程

第二版流程针对第一版的问题上做了一些改动:

  • 登录态token存储在Storage中
  • wx.login在进入登录页时调用

进入登录页调用wx.login,将code和执行的当前时间存储在内存中,code的有效期是5分钟,在用户点击按钮的点击事件中判断内存的存储时间是否已过5分钟,如果已过5分钟会调用wx.login重新存储code和执行的当前时间,在getphonenumber里面拿内存中的code和iv、encryptedData去请求服务端获取用户信息。

第二版流程的改进几乎消除了wx.login执行在getPhoneNumber的问题,因为从用户角度考虑是很少有用户在登录页停留5分钟以上的时间的,但是5分钟后的执行流程其实和第一版的流程是一样的,还会存在wx.login和getPhoneNumber的调用顺序的问题。

3、第三版流程

第三版流程和一、二版流程比较做了很大的改动,主要流程上加入了永久登录态这种对用户零感知的友好体验。

  • code是5分钟过期,而session_keyopen_id是永久有效
  • wx.login的调用时机变为任一页面的初始生命周期,且每次都调用

第三版流程改动主要是login的调用提前化,且无需客户端存储code这种5分钟过期的数据而是存储open_id这种永久有效的数据,只要在代码流程上不出错,就不会产生因为wx.login和getPhoneNumber的调用顺序而出错的问题。

永久登录态的实现:token、open_id和用户信息成映射关系,token过期的话,客户端通过login拿到open_id传给服务端,服务端可以在自己的数据库中根据open_id查询到用户信息,无需从微信服务重新获取。

注意两点:

  • 会话密钥 session_key 是对用户数据进行 加密签名 的密钥。为了应用自身的数据安全,开发者服务器不应该把会话密钥下发到小程序,也不应该对外提供这个密钥
  • open_id是用户的唯一标识,不能明文下发给客户端,需要做加密处理

最后

本文是一个前端小白从客户端的角度考虑的小程序登录流程,如果涉及内容有错误,欢迎各路大神提出指正。

文章分类
前端
文章标签