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


Posted in Javascript onDecember 12, 2018

小程序自上线以来,官方一直在调整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()
    })
  }
}

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

Javascript 相关文章推荐
javascript Array数组对象的扩展函数代码
May 22 Javascript
javascript高级程序设计第二版第十二章事件要点总结(常用的跨浏览器检测方法)
Aug 22 Javascript
今天是星期几的4种JS代码写法
Sep 17 Javascript
Position属性之relative用法
Dec 14 Javascript
js窗口震动小程序分享
Nov 28 Javascript
从零开始学习Node.js系列教程二:文本提交与显示方法
Apr 13 Javascript
vue的状态管理模式vuex
Nov 30 Javascript
vue使用better-scroll实现下拉刷新、上拉加载
Nov 23 Javascript
Vue Prop属性功能与用法实例详解
Feb 23 Javascript
Vue渲染过程浅析
Mar 14 Javascript
node.js中path路径模块的使用方法实例分析
Feb 13 Javascript
vue中控制mock在开发环境使用,在生产环境禁用方式
Apr 06 Vue.js
加快Vue项目的开发速度的方法
Dec 12 #Javascript
关于自定义Egg.js的请求级别日志详解
Dec 12 #Javascript
JS/HTML5游戏常用算法之碰撞检测 像素检测算法实例详解
Dec 12 #Javascript
d3绘制基本的柱形图的实现代码
Dec 12 #Javascript
JS/HTML5游戏常用算法之碰撞检测 地图格子算法实例详解
Dec 12 #Javascript
JS/HTML5游戏常用算法之追踪算法实例详解
Dec 12 #Javascript
js使用swiper实现层叠轮播效果实例代码
Dec 12 #Javascript
You might like
php中数字0和空值的区别分析
2014/06/05 PHP
php版淘宝网查询商品接口代码示例
2014/06/17 PHP
php几个预定义变量$_SERVER用法小结
2014/11/07 PHP
浅谈php优化需要注意的地方
2014/11/27 PHP
php快速排序原理与实现方法分析
2016/05/26 PHP
POST一个JSON格式的数据给Restful服务实例详解
2017/04/07 PHP
PHP面向对象之领域模型+数据映射器实例(分析)
2017/06/21 PHP
PHP 爬取网页的主要方法
2018/07/13 PHP
JavaScript下通过的XMLHttpRequest发送请求的代码
2011/06/28 Javascript
利用进制转换压缩数字函数分享
2014/01/02 Javascript
将HTML的左右尖括号等转义成实体形式的两种实现方式
2014/05/04 Javascript
js实现弹出窗口、页面变成灰色并不可操作的例子分享
2014/05/10 Javascript
JavaScript AJAX之惰性载入函数
2014/08/27 Javascript
javascript实现Table间隔色以及选择高亮(和动态切换数据)的方法
2015/05/14 Javascript
json+jQuery实现的无限级树形菜单效果代码
2015/08/27 Javascript
非常实用的12个jquery代码片段
2015/11/02 Javascript
通过原生JS实现为元素添加事件的方法
2016/11/23 Javascript
基于javascript实现按圆形排列DIV元素(一)
2016/12/02 Javascript
解决vue点击控制单个样式的问题
2018/09/05 Javascript
详解jQuery获取特殊属性的值以及设置内容
2018/11/14 jQuery
nodejs搭建本地服务器并访问文件操作示例
2019/05/11 NodeJs
vue使用video.js进行视频播放功能
2019/07/18 Javascript
JavaScript类的继承多种实现方法
2020/05/30 Javascript
js实现ajax的用户简单登入功能
2020/06/18 Javascript
JavaScript实现拖拽和缩放效果
2020/08/24 Javascript
Js数组扁平化实现方法代码总汇
2020/11/11 Javascript
python和pyqt实现360的CLable控件
2014/02/21 Python
Python实现按当前日期(年、月、日)创建多级目录的方法
2018/04/26 Python
解决python3.5 正常安装 却不能直接使用Tkinter包的问题
2019/02/22 Python
Django实现简单网页弹出警告代码
2019/11/15 Python
Django框架请求生命周期实现原理
2020/11/13 Python
波兰快递服务:Globkurier.pl
2019/11/08 全球购物
医学生自我评价
2014/01/27 职场文书
房屋买卖授权委托书
2014/09/27 职场文书
朝花夕拾读书笔记
2015/06/29 职场文书
Redis基本数据类型List常用操作命令
2022/06/01 Redis