微信小程序登陆流程详详详详解

小程序的登陆流程不同于网页端的登陆,步骤多较繁琐,这里主要讨论前端的具体实现。

一. 登陆流程详解

微信官方的流程图

微信官方的登陆图

  • 这个时序图信息量很多,我们把它拆解开来,代码上纵向我们只用关心“前端”,之后重点关心红框里的第一步和第二步,从简单入手。

1. 第一步:code换自定义登陆态

前端:

  • 使用微信api wx.login() 获取小程序的登录凭证code
  • 通过接口向后端发送code换取自定义登录态比如token,jwt等。
  • 如果需要统一微信平台下的身份,如微信公众号,或PC端的微信登陆用户,一般在登陆的同时会调用 wx.getUserInfo()获取到加密信息,再将加密数据通过后端接口返回给后端,之后拿到用户的openId或是unionId,确认用户身份。

提一下后端工作:

  • 拿到code,结合小程序 appId、小程序 appSecret向微信接口服务(微信服务器)发请求,拿到的返回值中有openIdsession_key等。这两项,一项是用户唯一标识,一项是会话密钥(用于解密微信的加密数据如手机号等,不是永久有效,所以称之为会话密钥,前端可用wx.checkSession()检测)
  • 拿到加密数据,使用上一步保存的session_key进行解密,之后得到有用的开放数据,进行数据储存或返回前端展示。

2. 第二步:储存自定义登陆态

  • 使用小程序的数据缓存,保存自定义登录态。

3. 附加的第三步

  • 自定义封装wx.request(),发起业务时带上自定义登陆态。
  • 在小程序生命周期onLuanch中加上登陆判定,如果登陆过就继续,如果没有登陆过则进行登陆操作等。

二. 上代码

  • 笔者单独将登陆作为一个页面,如若无此需求,也可将代码拆分。

login.wxml

  • 笔者的小程序是必须要获取用户信息的,所以直接在button授权获取用户信息的触发事件里,写登陆逻辑。
    非必要第一时间获取用户信息的小程序可直接在其他地方写登陆逻辑。
<!--login.wxml片段-->
<button open-type="getUserInfo" bindgetuserinfo="getUserInfo"></button>

login.js

  • showToast ():用wx.showToast()封装的函数,用于提示反馈
  • request():用wx.request()封装的基于promise的函数,可统一处理错误、带上登录态、权限判定等等。
Page({
  getUserInfo() {
    showToast('登陆中...', 'loading', true)
    wx.login({
      success: ({ code }) => {
        // 1. 拿到code发送给后端
        request({
          url: '/wechat/mini/token',
          data: { code }
        }).then(({ data: { result } }) => {
          // 2. 将token储存
          wx.setStorageSync('token', result.token)
            
          wx.getUserInfo({
            success: data => {
              // 3. 将加密用户信息发送至后端解密
              request({
                url: '/wechat/mini/userinfo',
                data: {
                  token: result.token,
                  payload: data
                },
                method: 'POST'
              }).then(({ data: { result } }) => {
                wx.showToast({ title: '登陆成功', icon: 'success' })
                // 保存用户信息
                wx.setStorageSync('userinfo', result)
                // 跳转页面...
              })
            },
            fail: () => {
              showToast('请授权用户信息后重试!')
            }
          })
        })
      },
      fail() {
        showToast('网络状况不佳,请检查网络后重试!')
      }
    })
  }
})

request.js

使用wx.request()封装的基于Promise的函数。

const request = ({ url, data = {}, method = 'GET' }) => {
  return new Promise((resolve, reject) => {
    wx.request({
      url,
      data,
      method,
      // 一种做法,在header中带上登录态,方式取决于和后端的约定
      header: {
        Authorization: wx.getStorageSync('token')
      },
      success: res => {
        if (res.statusCode === 200) {
          resolve(res)
        } else {
          // 自定义错误处理 
          reject()
          if (res.statusCode === 403) {
            ...
          } else if (res.statusCode === 401) {
            ...
          }
        }
      },
      fail: () => {
        reject()
        showToast('请求失败,请检查网络后重试!')
      }
    })
  })
}

export default request

app.js

如果是必要登录的小程序,可在app.js中去判断登录态和登陆态时效,以跳转登陆。

App({
  onLaunch() {
    const token = wx.getStorageSync('token')

    if (!token) {
      wx.reLaunch({ url: '/pages/login/login' })
    }
  }
})

三. 扩展提升:小朋友,你是不是有很多的问号?

1. 为什么要用wx.login()微信api,为什么不能用户名密码登陆?

  • 小程序运行在微信客户端内部,遵循微信的机制就可以获取到用户的很多信息,比如昵称、头像url、性别、省份、城市、国家,以及加密信息openId(同一应用下唯一标识)、unionId(微信平台唯一标识)、手机号、微信号等等。使用wx.login()获取code是拿到这一系列信息的第一步

2. 用户唯一标识为什么不能用微信号,openId和unionId是什么?

  • 微信号在第一次注册微信之后会有一次修改机会,所以不能用微信号作为用户唯一标识
  • openId是用户在同一应用下的唯一标识,换句话说,就是一个用户登陆了小程序,之后用户改了微信号再次登陆或者是其他操作,用户的openId是不变的,可以用来当作唯一标识。
  • unionId用微信的原话解释:只要是同一个微信开放平台帐号下的移动应用、网站应用和公众帐号(包括小程序),用户的 unionId是唯一的。
  • ps:如果未涉及到微信开放平台的用户同一,即如果只是单一应用,就不用管unionId。

3. 如何判断登陆态过期?

  • 后端向前端签发的登录态一般是存在过期时间的。
  • 小程序没有浏览器的cookie来进行定时储存
  • 提供一种解决方法,可以让后端在签发登录态时,顺便加上登录态过期时间戳这样每次打开小程序的onLaunch的时候进行判断,如果快要过期则重新请求刷新登录态
  • 当然也可能或许大概存在用户连续使用小程序24小时或更久不关闭,导致登录态直接过期的情况,针对这种情况,就要特殊处理了,这里不再赘述。

4. 为什么不使用bindgetuserinfo回调的detail来获取用户信息?

  • 拿到用户信息必须使用button来触发授权,用户在点击授权之后,一可以从button绑定的bindgetuserinfo回调事件中的e.detail.userInfo拿到,二在授权之后就可以用wx.getUserInfo()随时获取到用户信息。
  • 如果不需要解密数据,以上两种二选一。
  • 注意:当需要后端解密的时候,顺序很关键必须要先调用wx.login()拿到code,等同于后端先拿到session_key,再将加密数据给后端解密才能成功。
  • 代码里先触发了bindgetuserinfo,如果用回调的detail解密,就等于wx.login()在后,顺序颠倒,则解密失败。所以在这里额外用wx.getUserInfo()来获取用户信息。

博主初来乍到,文笔不加,如有错误和疑问,欢迎留言加关注,共同学习进步!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容