小程序实现授权登陆的解决方案


Posted in Javascript onDecember 02, 2018

前言

之前写过一个关于微信授权登陆的文章

传送门

最近在做小程序的项目,依旧是商城,又开始研究微信的登陆授权坑,第一次接触小程序,授权登陆也是一塌糊涂以后再慢慢的改进

场景

  • 微信用户可以通过搜索进入小程序
  • 也可以通过别人分享进入小程序
  • 进入小程序之后需要用户授权拿到用户信息进行注册

代码实现

初始化页面home页用户第一次进入小程序必须授权后台注册并登陆

app.json

{
"pages": [
  "pages/home/index", 
  "pages/login/index",
   ...
  ]
}

login.js逻辑进入页面判断一下是不是授权过,判断用户是否已经授权,已经授权显示登陆,没有授权显示授权,用户无论是注册还是登陆用的是后台提供的同一个接口。返回token存在本地

login.js

const App = getApp()
import { loginModel } from '../../models/login.js'
import { MineModel } from '../../models/mine.js'
import { encodeUnicode } from '../../utils/index.js'
const ModelLogin = new loginModel()
const Modelmine = new MineModel()
Page({
 data: {
  logged: !1,
  isauth: false,
  locked: false
 },
 onLoad: function(options) {
  // 返回到之前要刷新
  var pages = getCurrentPages() // 获取页面栈
  var prevPage = pages[pages.length - 2] // 前一个页面
  prevPage.setData({
   isBack: true
  })
 },
 onShow: function() {
  // 如果已经授权则显示登录,直接登录不调用授权
  App.WxService.getSetting().then(res => {
   if (res.authSetting['scope.userInfo']) {
    this.setData({
     isauth: true
    })
   }
  })
  //token 不能在page外面定义,变量写在 page 外面有缓存
  const token = App.WxService.getStorageSync('utoken')
  // 如果有token显示已经授权
  this.setData({
   logged: !!token
  })
  token && setTimeout(this.goBack, 1500)
 },
 login() {
  this.wechatSignUp()
 },
 goBack() {
  // 返回登录之前的页面
  wx.navigateBack({
   delta: 1
  })
 },
 // 登陆注册
 wechatSignUp(cd) {
  // 上锁如果正在请求接口那么就返回
  if (this.data.locked) {
   return
  }
  this.data.locked = true
  //注册或者登陆获取token
  let code = ''
  App.WxService
   .login()
   .then(data => {
    code = data.code
    wx.setStorageSync('logincode', data.code)
    return App.WxService.getUserInfo()
   })
   .then(data => {
    // 请求后台登录注册接口
    return ModelLogin.wechatSignUp({
     encrypteData: data.encryptedData,
     iv: data.iv,
     rawData: encodeUnicode(data.rawData), // 编码
     signature: data.signature,
     code: code
    })
   })
   .then(data => {
    this.data.locked = false
    if (data.data.token == '') {
     wx.showToast({
      title: '登录失败',
      icon: 'none'
     })
     return
    }
    App.WxService.setStorageSync('utoken', data.data.token)
    // 访问后台接口获取用户信息
    ModelLogin.getVipInfo({ token: data.data.token }).then(res => {
     App.globalData.userInfo = res.data.userInfo
     // 返回上一页
     this.goBack()
    })
   })
   .catch(err => {
    this.data.locked = false
    console.log(err)
   })
 }
})

这里的App.WxService等价于wx因为wx是回调的方式,这里使用的是promise。

先判断有没有授权,没有授权显示点击授权,有授权显示点击登录,调用的方法都是wechatSignUp,拿到wx.login的code和wx.getUserInfo的数据给后台,然后后台返回token,然后再去访问后台获取用户信息

login的逻辑大概就是这些

login.wxml

<view class="login-container">
 <view class="login" wx:if="{{ !logged }}">
  <view class="app-info">
   <image class="app-logo" src="./s-toplogo@2x.png" />
   <text class="app-name">商城</text>
  </view>
  <view class="alert">
   <view class="alert-title" wx:if="{{!isauth}}">请同意授权</view>
   <view class="alert-title" wx:if="{{isauth}}">请登录</view>
   <view class="alert-desc">
    <view class="alert-text">为了让头号买手可以更好的为您服务</view>
   </view>
  </view>
  <button type='primary' wx:if="{{!isauth}}" class="sui-f16" open-type="getUserInfo" bind:getuserinfo="wechatSignUp">确认授权</button>
  <button type="primary" wx:if="{{isauth}}" class="weui-btn" bindtap="login">确认登录</button>
 </view>
 <view class="logged" wx:else>
  <image class="logged-icon" src="./s-toplogo@2x.png" />
  <view class="logged-text">近期你已经授权登陆过商城</view>
  <view class="logged-text">自动登录中</view>
 </view>
</view>

访问后台接口的时候在header里传token如果后台没有拿到token就返回401,前端统一拦截跳转到登陆页面

结束

关于app.js本来打算在app做拦截的,但是异步请求总是在进入页面后才拿到后台返回的数据,因为用户可能从商品详情页等其他页面进入小程序,授权后要返回进入页面,在app.js中拦截就无法返回页面了,所以就直接在页面的js里去判断,还好可以分享的页面不多所以就没有在app.js里写任何东西。第一次接触,希望以后能优化了再发文记录一下

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JavaScript 数组循环引起的思考
Jan 01 Javascript
jquery 如何动态添加、删除class样式方法介绍
Nov 07 Javascript
使用javascript实现Iframe自适应高度
Dec 24 Javascript
Javascript实现Web颜色值转换
Feb 05 Javascript
jQuery源码分析之Callbacks详解
Mar 13 Javascript
JS+CSS实现电子商务网站导航模板效果代码
Sep 10 Javascript
Javascript对象字面量的理解
Jun 22 Javascript
浅谈Node Inspector 代理实现
Oct 19 Javascript
JS几个常用的函数和对象定义与用法示例
Jan 15 Javascript
vue实现自定义多选按钮
Jul 16 Javascript
如何基于jQuery实现五角星评分
Sep 02 jQuery
简单谈谈offsetleft、offsetTop和offsetParent
Dec 04 Javascript
mpvue 单文件页面配置详解
Dec 02 #Javascript
Vuejs监听vuex中值的变化的方法示例
Dec 02 #Javascript
详解Vue一个案例引发「内容分发slot」的最全总结
Dec 02 #Javascript
在移动端使用vue-router和keep-alive的方法示例
Dec 02 #Javascript
Angular6 Filter实现页面搜索的示例代码
Dec 02 #Javascript
GOJS+VUE实现流程图效果
Dec 01 #Javascript
JavaScript实现简单轮播图效果
Dec 01 #Javascript
You might like
php include和require的区别深入解析
2013/06/17 PHP
php表单请求获得数据求和示例
2014/05/15 PHP
php打造智能化的柱状图程序,用于报表等
2015/06/19 PHP
php使用APC实现实时上传进度条功能
2015/10/26 PHP
基于jquery的自定义鼠标提示效果 jquery.toolTip
2010/11/14 Javascript
深入理解JavaScript系列(13) This? Yes,this!
2012/01/18 Javascript
jquery数据验证插件(自制,简单,练手)实例代码
2013/10/24 Javascript
javascript学习笔记之10个原生技巧
2014/05/21 Javascript
JS中getYear()和getFullYear()区别分析
2014/07/04 Javascript
JS按回车键实现登录的方法
2014/08/25 Javascript
Javascript实现图片轮播效果(二)图片序列节点的控制实现
2016/02/17 Javascript
vue日期组件 支持vue1.0和2.0
2017/01/09 Javascript
Bootstrap table使用方法汇总
2017/11/17 Javascript
vue+webpack模拟后台数据的示例代码
2018/07/26 Javascript
通过实例了解js函数中参数的传递
2019/06/15 Javascript
微信小程序仿通讯录功能
2020/04/09 Javascript
如何编写一个 Webpack Loader的实现
2020/10/18 Javascript
[01:21:36]CHAOS vs Alliacne 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/16 DOTA
python安装numpy&amp;安装matplotlib&amp; scipy的教程
2017/11/02 Python
利用Python暴力破解zip文件口令的方法详解
2017/12/21 Python
Python简单实现查找一个字符串中最长不重复子串的方法
2018/03/26 Python
利用Python正则表达式过滤敏感词的方法
2019/01/21 Python
Python range、enumerate和zip函数用法详解
2019/09/11 Python
详解tf.device()指定tensorflow运行的GPU或CPU设备实现
2021/02/20 Python
HTML5-WebSocket实现聊天室示例
2016/12/15 HTML / CSS
国际鲜花速递专家:Floraqueen
2016/11/24 全球购物
PAUL HEWITT手表美国站:德国北部时尚生活配饰品牌,船锚元素
2017/11/18 全球购物
狗狗玩具、零食和咀嚼物的月度送货服务:Super Chewer
2018/08/22 全球购物
Unix如何在一行中运行多个命令
2015/05/29 面试题
室内设计自我鉴定
2013/10/15 职场文书
安全责任书范本
2014/04/15 职场文书
幼儿园法制宣传日活动总结
2014/11/01 职场文书
募捐感谢信
2015/01/22 职场文书
2016秋季小学开学寄语
2015/12/03 职场文书
2016年主题党日活动总结
2016/04/05 职场文书
2019入党申请书格式和范文
2019/06/25 职场文书