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


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 相关文章推荐
js arguments.callee的应用代码
May 07 Javascript
js 强制弹出窗口代码研究-又一款代码
Mar 20 Javascript
javascript中Function类型详解
Apr 28 Javascript
JS数组array元素的添加和删除方法代码实例
Jun 01 Javascript
js中数组的常用方法小结
Dec 30 Javascript
深入理解React高阶组件
Sep 28 Javascript
JavaScript实现为事件句柄绑定监听函数的方法分析
Nov 14 Javascript
详解Node.js 中使用 ECDSA 签名遇到的坑
Nov 26 Javascript
微信小程序系列之自定义顶部导航功能
May 21 Javascript
6种JavaScript继承方式及优缺点(小结)
Feb 06 Javascript
javascript 设计模式之享元模式原理与应用详解
Apr 08 Javascript
基于vue实现探探滑动组件功能
May 29 Javascript
加快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
GD输出汉字的函数的分析
2006/10/09 PHP
php中全局变量global的使用演示代码
2011/05/18 PHP
PHP使用GIFEncoder类处理gif图片实例
2014/07/01 PHP
php使用get_class_methods()函数获取分类的方法
2016/07/20 PHP
thinkPHP5框架导出Excel文件简单操作示例
2018/08/03 PHP
PHP添加PNG图片背景透明水印操作类定义与用法示例
2019/03/12 PHP
phpinfo的知识点总结
2019/10/10 PHP
javascript 文档的编码问题解决
2009/03/01 Javascript
JavaScript中的作用域链和闭包
2012/06/30 Javascript
一个简单的瀑布流效果(主体形式自写)
2013/05/27 Javascript
Jquery中LigerUi的弹出编辑框(实现方法)
2013/07/09 Javascript
JS仿百度搜索自动提示框匹配查询功能
2013/11/21 Javascript
jquery如何根据值设置默认的选中项
2014/03/17 Javascript
bootstrap table 服务器端分页例子分享
2015/02/10 Javascript
js禁止页面刷新与后退的方法
2015/06/08 Javascript
基于JS实现PHP的sprintf函数实例
2015/11/14 Javascript
BootStrap 导航条实例代码
2017/05/18 Javascript
angularjs实现猜数字大小功能
2020/05/20 Javascript
angular中子控制器向父控制器传值的实例
2018/10/08 Javascript
Node4-5静态资源服务器实战以及优化压缩文件实例内容
2019/08/29 Javascript
javascript跳转与返回和刷新页面的实例代码
2019/11/20 Javascript
解决vuex数据页面刷新后初始化操作
2020/07/26 Javascript
[03:42]2014DOTA2西雅图国际邀请赛 Navi战队巡礼
2014/07/07 DOTA
详解如何使用Python编写vim插件
2017/11/28 Python
Python分布式进程中你会遇到的问题解析
2019/05/28 Python
关于Numpy中的行向量和列向量详解
2019/11/30 Python
Python调用.NET库的方法步骤
2019/12/27 Python
python爬虫开发之urllib模块详细使用方法与实例全解
2020/03/09 Python
python 引用传递和值传递详解(实参,形参)
2020/06/05 Python
HTML5之SVG 2D入门2—图形绘制(基本形状)介绍及使用
2013/01/30 HTML / CSS
世界上最大的巴士旅游观光公司:Big Bus Tours
2016/10/20 全球购物
美国第一大药店连锁机构:Walgreens(沃尔格林)
2019/10/10 全球购物
阿玛尼美妆俄罗斯官网:Giorgio Armani Beauty RU
2020/07/19 全球购物
迪卡侬波兰体育用品商店:Decathlon波兰
2020/03/31 全球购物
党的群众路线教育实践活动个人对照检查材料(教师)
2014/11/04 职场文书
详细总结Python常见的安全问题
2021/05/21 Python