新版小程序登录授权的方法

所属分类: 网络编程 / JavaScript 阅读数: 1195
收藏 0 赞 0 分享

小程序自上线以来,官方一直在调整API,因此也出现了一批被废弃的接口,作为程序员的我们,此时此刻千万不能为这不断的变化而感到头疼,应当与时俱进,不断的更新自己的知识储备和应用技能。

首先近期工作中需要做小程序框架升级,升级成美团开源的mpvue框架;然后因为微信小程序API的改版,所以也顺便将授权登录的逻辑重新设计了。

新旧对比:

旧的方法:旧方法wx.getUserInfo按照用户登录时,弹出需要授权的弹窗,用户点击授权后才能使用。

新方法:Open-data的灵活使用方法,不会让你直接获得用户信息,而是小程序点击登录按钮获取用户头像,就是使用 button 组件,并将 open-type 指定为 getUserInfo 类型,获取用户基本信息。

授权登录的逻辑参考了多个小程序,希望能找到最优的模式。下面会配合代码详细讲解整个流程。

模式概览

由于微信小程序的改版导致直接弹出授权的登录方式将逐渐不再支持,受影响的有wx.getUserInfo接口,以及wx.authorize接口传入scope=”scope.userInfo”的情况。所以需要重新设计一套合适的登录授权流程。整体流程如下图:

主动登录

由于APP中有些页面默认需要登录的,如[个人中心]页面,需要登录获取到用户信息,才能继续操作。这样的页面就需要在每次进入页面(onShow)时判断是否授权了。

profile页面

onShow () {
  login(() => {
    do something...
  })
}

关于登录授权相关的逻辑都可以封装在handleLogin.js

handleLogin.js

// 开始login
function login (callback) {
 wx.showLoading()
 wx.login({
  success (res) {
   if (res.code) {
    // 登录成功,获取用户信息
    getUserInfo(res.code, callback)
   } else {
    // 否则弹窗显示,showToast需要封装
    showToast()
   }
  },
  fail () {
   showToast()
  }
 })
}

// 获取用户信息
function getUserInfo (code, callback) {
 wx.getUserInfo({
  // 获取成功,全局存储用户信息,开发者服务器登录
  success (res) {
   // 全局存储用户信息
   store.commit('storeUpdateWxUser', res.userInfo)
   postLogin(code, res.iv, res.encryptedData, callback)
  },
  // 获取失败,弹窗提示一键登录
  fail () {
   wx.hideLoading()
   // 获取用户信息失败,清楚全局存储的登录状态,弹窗提示一键登录
   // 使用token管理登录态的,清楚存储全局的token
   // 使用cookie管理登录态的,可以清楚全局登录状态管理的变量
   store.commit('storeUpdateToken', '')
   // 获取不到用户信息,说明用户没有授权或者取消授权。弹窗提示一键登录,后续会讲
   showLoginModal()
  }
 })
}

// 开发者服务端登录
function postLogin (code, iv, encryptedData, callback) {
 let params = {
  code: code,
  iv: iv,
  encryptedData: encryptedData
 }
 request(apiUrl.postLogin, params, 'post').then((res) => {
  if (res.code == 1) {
   wx.hideLoading()
   // 登录成功,
   // 使用token管理登录态的,存储全局token,用于当做登录态判断,
   // 使用cookie管理登录态的,可以存任意变量当做已登录状态
   store.commit('storeUpdateToken', res.data.token)
   callback && callback()
  } else {
   showToast()
  }
 }).catch((err) => {
  showToast()
 })
}

// 显示toast弹窗
function showToast (content = '登录失败,请稍后再试') {
 wx.showToast({
  title: content,
  icon: 'none'
 })
}

到此为止,登录就算完成了。不管使用token还是cookie都可以,都能有正常的登录态了,可以执行后续操作。

整个流程是 wx.login => wx.getUserInfo => 开发者服务器登录postLogin

调用接口

某些页面默认不需要登录,但某些用户操作事件是需要登录状态的,所以一者可以判断全局存储的登录状态管理的变量,如果为false,那么直接可以弹窗提示需要一键登录。二者如果全局状态为true,则调用接口看接口返回的code是否是未登录状态(此情况一般来说是登录态过期),未登录的话也弹窗提示需要一键登录。

某页面(需登录的用户操作)

getPlayer () {
  // 判断全局是否有登录状态,如果没有直接弹窗提示一键登录
  isLogin(() => {
    let params = {
      token: this.token
    }
    request(apiUrl.getPlayer, params).then((res) => {
      // TODO: 删除打印
      if (res.code === 1) {
        store.commit('storeUpdateUser', res.data.player_info)
      } else {
        // 获取失败了,如果是code是未登录,则去登录,然后执行回调函数this.getPlayer
        // 如果code不是未登录,直接弹窗报错误信息
        handleError(res, this.getPlayer)
      }
    }).catch((err) => {
      handleError(err)
    })
  })
}

handleLogin.js

// 判断是否登录
function isLogin (callback) {
 let token = store.state.token
 if (token) {
  // 如果有全局存储的登录态,暂时认为他是登录状态
  callback && callback()
 } else {
  // 如果没有登录态,弹窗提示一键登录
  showLoginModal()
 }
}

// 接口调用失败处理,
function handleError (res, callback) {
 // 规定-3041和-3042分别代表未登录和登录态失效
 if (res.code == -3041 || res.code == -3042) {
  // 弹窗提示一键登录
  showLoginModal()
 } else if (res.msg) {
  // 弹窗显示错误信息
  showToast(res.msg)
 }
}

到此为止,需要登录的用户操作就可以处理了。如果全局登录状态变量为true,先去调用接口,根据返回的信息是否是未登录再处理。

弹窗提示

由于微信小程序授权的接口wx.getUserInfowx.authorize中scope 为 “scope.userInfo” ,新版中调用这两个API是不会主动触发弹出授权窗口的。需要使用<button open-type="getUserInfo"></button>方法。

上面代码中多处出现的showLoginModal是用于显示一键登录的。如下:

handleLogin.js

// 显示一键登录的弹窗
function showLoginModal () {
 wx.showModal({
  title: '提示',
  content: '你还未登录,登录后可获得完整体验 ',
  confirmText: '一键登录',
  success (res) {
   // 点击一键登录,去授权页面
   if (res.confirm) {
    wx.navigateTo({
     url: '授权登录页面地址',
    })
   }
  }
 })
}

关于授权登录,我们做了一个专门的页面处理,此处的button<button type="primary" v-if="canIUse" open-type="getUserInfo" @getuserinfo="getUserInfo">微信登录</button>。如下:

getUserInfo (e) {
  if (e.target.userInfo) {
    // 点击Button弹窗授权,如果授权了,执行login
    // 因为Login流程中有wx.getUserInfo,此时就可以获取到了
    login(() => {
      // 登录成功后,返回
      wx.navigateBack()
    })
  }
}

到此为止,整个授权和登录流程就算走完了。可以回过头梳理一下最开始的流程图,应该就能理清整个逻辑了。

更多精彩内容其他人还在看

AngularJs IE Compatibility 兼容老版本IE

本文主要介绍AngularJs IE Compatibility 兼容老版本IE的问题及解决办法,有兴趣的小伙伴可以参考下
收藏 0 赞 0 分享

AngularJs Modules详解及示例代码

本文主要介绍AngularJs Modules的相关知识,这里整理了详细的资料及简单示例代码,有兴趣的朋友可以参考下
收藏 0 赞 0 分享

AngularJs Scope详解及示例代码

本文主要介绍AngularJs Scope的知识,这里整理了详细资料及示例代码,有兴趣的小伙伴可以参考下
收藏 0 赞 0 分享

node.js中module.exports与exports用法上的区别

Node.js 引入了模块(Module)概念,一个模块可以通过module.exports 或 exports 将函数、变量等导出,以使其它 JavaScript 脚本通过require() 函数引入并使用。那么node.js中module.exports与exports有什么
收藏 0 赞 0 分享

基于JS实现发送短信验证码后的倒计时功能(无视页面刷新,页面关闭不进行倒计时功能)

这篇文章主要介绍了基于JS实现发送短信验证码后的倒计时功能(无视页面刷新,页面关闭不进行倒计时功能)的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享

基于jQuery实现发送短信验证码后的倒计时功能(无视页面关闭)

最近做了一个项目,其中有需求要求实现发送短信验证码后倒计时功能,其中有个难点:要求关闭页面也进行倒计时。好吧,下面小编把jquery 发送验证码倒计时的实现代码分享给大家,大家可以参考下
收藏 0 赞 0 分享

js绘制购物车抛物线动画

这篇文章主要为大家详细介绍了js绘制购物车抛物线动画,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

vue.js入门教程之绑定class和style样式

小编之前介绍了通过vue.js计算属性,不知道大家都学会了吗。那这篇文章中我们将一起学习vue.js实现绑定class和style样式,有需要的朋友们可以参考借鉴。
收藏 0 赞 0 分享

纯JS实现可拖拽表单的简单实例

下面小编就为大家带来一篇纯JS实现可拖拽表单的简单实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

js实现StringBuffer的简单实例

下面小编就为大家带来一篇js实现StringBuffer的简单实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享
查看更多