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


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 相关文章推荐
jQuery.autocomplete 支持中文输入(firefox)修正方法
Mar 10 Javascript
Extjs中使用extend(js继承) 的代码
Mar 15 Javascript
JavaScript取得鼠标绝对位置程序代码介绍
Sep 16 Javascript
使用js实现的简单拖拽效果
Mar 18 Javascript
简单实现兼容各大浏览器的js复制内容到剪切板
Sep 09 Javascript
javascript for-in有序遍历json数据并探讨各个浏览器差异
Nov 30 Javascript
微信小程序 页面跳转及数据传递详解
Mar 14 Javascript
JS使用插件cryptojs进行加密解密数据实例
May 11 Javascript
深入理解requireJS-实现一个简单的模块加载器
Jan 15 Javascript
使用react context 实现vue插槽slot功能
Jul 18 Javascript
压缩Vue.js打包后的体积方法总结(Vue.js打包后体积过大问题)
Feb 03 Javascript
9种方法优化jQuery代码详解
Feb 04 jQuery
加快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提取字符串中的图片地址[正则表达式]
2011/11/12 PHP
php递归法读取目录及文件的方法
2015/01/30 PHP
使用PHPExcel实现数据批量导出为excel表格的方法(必看)
2017/06/09 PHP
php输出反斜杠的实例方法
2019/09/19 PHP
js 发个判断字符串是否为符合标准的函数
2009/04/27 Javascript
jQuery ctrl+Enter shift+Enter实现代码
2010/02/07 Javascript
javascript 冒泡排序 正序和倒序实现代码
2010/12/14 Javascript
再谈querySelector和querySelectorAll的区别与联系
2012/04/20 Javascript
js实现可兼容IE、FF、Chrome、Opera及Safari的音乐播放器
2015/02/11 Javascript
JavaScript兼容性总结之获取非行间样式案例
2016/08/07 Javascript
Javascript中判断一个值是否为undefined的方法详解
2016/09/28 Javascript
JS回调函数基本定义与用法实例分析
2017/05/24 Javascript
JavaScript实现删除数组重复元素的5种常用高效算法总结
2018/01/18 Javascript
vue 返回上一页,页面样式错乱的解决
2019/11/14 Javascript
layui清除radio的选中状态实例
2019/11/14 Javascript
vue相关配置文件详解及多环境配置详细步骤
2020/05/19 Javascript
通过vue.extend实现消息提示弹框的方法记录
2021/01/07 Vue.js
ajax jquery实现页面某一个div的刷新效果
2021/03/04 jQuery
[07:20]2014DOTA2西雅图国际邀请赛 选手讲解积分赛第二天
2014/07/11 DOTA
python实现跨excel的工作表sheet之间的复制方法
2018/05/03 Python
浅谈Python脚本开头及导包注释自动添加方法
2018/10/27 Python
pycharm new project变成灰色的解决方法
2019/06/27 Python
关于pandas的离散化,面元划分详解
2019/11/22 Python
Python实现爬取网页中动态加载的数据
2020/08/17 Python
澳大利亚实惠时尚女装商店:Katies
2019/06/16 全球购物
Unineed中文官网:高端护肤美妆与时尚配饰,英国直邮
2020/07/23 全球购物
客服实习的个人自我鉴定
2013/10/20 职场文书
《晏子使楚》教学反思
2014/02/08 职场文书
校庆筹备方案
2014/03/30 职场文书
应届生求职信
2014/05/31 职场文书
土地租赁协议书
2015/01/29 职场文书
索赔员岗位职责
2015/02/15 职场文书
2015年六一儿童节演讲稿
2015/03/19 职场文书
2015年国庆节标语大全
2015/07/30 职场文书
爱护公物主题班会
2015/08/17 职场文书
如何起草一份正确的合伙创业协议书?
2019/07/04 职场文书