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


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 相关文章推荐
jquery 子窗口操作父窗口的代码
Sep 21 Javascript
JQuery之拖拽插件实现代码
Apr 14 Javascript
jQuery下的动画处理总结
Oct 10 Javascript
解析prototype,JQuery中跳出each循环的方法
Dec 12 Javascript
Javascript中的作用域和上下文深入理解
Jul 03 Javascript
基于javascript实现单选及多选的向右和向左移动实例
Jul 25 Javascript
原生js编写焦点图效果
Dec 08 Javascript
JSON对象转化为字符串详解
Aug 11 Javascript
使用Layer组件弹出多个对话框(非嵌套)与关闭及刷新的例子
Sep 25 Javascript
vue radio单选框,获取当前项(每一项)的value值操作
Sep 10 Javascript
原生js+css实现tab切换功能
Sep 17 Javascript
Vue实现boradcast和dispatch的示例
Nov 13 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
在WIN98下以apache模块方式安装php
2006/10/09 PHP
php数组函数序列之array_intersect() 返回两个或多个数组的交集数组
2011/11/10 PHP
php字符编码转换之gb2312转为utf8
2013/10/28 PHP
浅析ThinkPHP中execute和query方法的区别
2014/06/13 PHP
thinkPHP实现表单自动验证
2014/12/24 PHP
php隐藏实际地址的文件下载方法
2015/04/18 PHP
Yii2汉字转拼音类的实例代码
2017/04/18 PHP
Thinkphp开发--集成极光推送
2017/09/15 PHP
js parseInt(&quot;08&quot;)未指定进位制问题
2010/06/19 Javascript
jQuery中的bind绑定事件与文本框改变事件的临时解决方法
2010/08/13 Javascript
JavaScript下利用fso判断文件是否存在的代码
2010/12/11 Javascript
利用毫秒减值计算时长的js代码
2013/09/22 Javascript
JS验证身份证有效性示例
2013/10/11 Javascript
JS将数字转换成三位逗号分隔的样式(示例代码)
2014/02/19 Javascript
jQuery.holdReady()方法用法实例
2014/12/27 Javascript
jquery利用命名空间移除绑定事件的方法
2015/03/11 Javascript
JS实现弹出浮动窗口(支持鼠标拖动和关闭)实例详解
2015/08/06 Javascript
学习JavaScript设计模式之策略模式
2016/01/12 Javascript
Bootstrap编写一个兼容主流浏览器的受众巨幕式风格页面
2016/07/01 Javascript
Nodejs之http的表单提交
2017/07/07 NodeJs
Three.js实现绘制字体模型示例代码
2017/09/26 Javascript
[01:25:09]2014 DOTA2国际邀请赛中国区预选赛 5 23 CIS VS DT第二场
2014/05/24 DOTA
Python处理中文标点符号大集合
2018/05/14 Python
Python中安装easy_install的方法
2018/11/18 Python
django和flask哪个值得研究学习
2020/07/31 Python
Python 中如何写注释
2020/08/28 Python
45个非常奇妙的CSS3 特性应用示例
2012/01/01 HTML / CSS
美国Max仓库:Max Warehouse
2020/05/31 全球购物
2013年大学生的自我鉴定
2013/10/24 职场文书
测试工程师岗位职责
2013/11/28 职场文书
企业门卫岗位职责
2013/12/12 职场文书
致跳远运动员加油稿
2014/02/11 职场文书
井冈山红色之旅心得体会
2014/10/07 职场文书
CSS 实现多彩、智能的阴影效果
2021/05/12 HTML / CSS
Tomcat配置访问日志和线程数
2022/05/06 Servers
vue本地构建热更新卡顿的问题“75 advanced module optimization”完美解决方案
2022/08/05 Vue.js