详解vue微信网页授权最终解决方案


Posted in Javascript onJune 16, 2019

vue微信网页授权,基于vue-cli3.0+webpack 4+vant ui + sass+ rem适配方案+axios,开发的微信授权方案。项目地址:vue-wechat-auth

参考了[vue-wechat-login],思路有些不同,本文基于进入所有页面都必须先授权的操作。

与之前写的授权不同之处

这次的逻辑全部在router的beforeEach进行,相较更加简洁明。之前是在一个中间页author.vue中,加上微信授权要跳转很多次

在这里你能找到

微信网页授权前端解决方案,官方文档

如何使用Natapp(ngrok)进行微信本地开发调试,官方文档

如何配置微信开发测试账号

关于测试账号和本地开发设置

由于文章过长这里[微信测试账号和本地开发调试]记得回来哦~

微信网页授权

都设置好了那就开始微信网页开发第一步也是最重要的一步,微信网页授权

关于授权你首先要清楚的是,服务端要用到的是微信openid还是微信unionid,这两者的区别是,如果你要的是unionid,那么你需要在[微信开放平台]去绑定测试账号。测试号的appId和appsecret在微信公众平台的测试号里找。微信公众号后台->开发者工具->公众平台测试帐号->进入

详解vue微信网页授权最终解决方案

如果你不需要unionid,那这个你就可以省略, 如果服务端是需要unionid的那不绑定的话授权会把报错的。记得问一下服务端开发人员哦。

开发

首先我们看下微信授权的流程图,关于微信网页授权

前端需要做的是

第一步:用户同意授权,获取code,拼接微信授权地址,redirect_uri就是你的当前地址,关于appid有些人是通过接口获取的,我这里就直接写在项目全局变量里了VUE_APP_WECHAT_APPID,用户授权成功后微信会携带code和status跳回来

https://open.weixin.qq.com/connect/oauth2/authorize?appid=${this.appid}&redirect_uri=${this.redirect_uri}&response_type=code&scope=${

this.scope}&state=${this.state}#wechat_redirect

第二步,访问登录接口,将code传给服务端,小哥哥进行一系列的操作,通过code换取网页授权access_token,拉取用户信息(需scope为 snsapi_userinfo),返回是否登录成功,成功后返回用户信息和登录令牌 token

详解vue微信网页授权最终解决方案

在permission.js中路由拦截进行这一系列操作,代码注释很详细了

permission.js

import router from './router'
import store from './store'
import getPageTitle from '@/utils/get-page-title'
import wechatAuth from './plugins/wechatAuth' // 微信登录插件
const qs = require('qs')

router.beforeEach((to, from, next) => {
 const loginStatus = Number(store.getters.loginStatus)
 console.log('loginStatus=' + loginStatus)
 console.log('token=' + store.getters.token)
 // 页面标题
 document.title = getPageTitle(to.meta.title)
 if (loginStatus === 0) {
 // 微信未授权登录跳转到授权登录页面
 const url = window.location.href
 // 解决重复登录url添加重复的code与state问题
 const parseUrl = qs.parse(url.split('?')[1])
 let loginUrl
 if (parseUrl.code && parseUrl.state) {
 delete parseUrl.code
 delete parseUrl.state
 loginUrl = `${url.split('?')[0]}?${qs.stringify(parseUrl)}`
 } else {
 loginUrl = url
 }
 // 设置微信授权回调地址
 wechatAuth.redirect_uri = loginUrl
 // 无论拒绝还是授权都设置成1
 store.dispatch('user/setLoginStatus', 1)
 // 跳转到微信授权页面
 window.location.href = wechatAuth.authUrl
 } else if (loginStatus === 1) {
 // 用户已授权,获取code
 try {
 // 通过回调链接设置code status
 wechatAuth.returnFromWechat(to.fullPath)
 } catch (err) {
 // 失败,设置状态未登录,刷新页面
 store.dispatch('user/setLoginStatus', 0)
 location.reload()
 }
 // 同意授权 to.fullPath 携带code参数,拒绝授权没有code参数
 const code = wechatAuth.code
 if (code) {
 // 拿到code 访问服务端的登录接口
 store
 .dispatch('user/loginWechatAuth', code)
 .then(res => {
  // 成功设置已登录状态
  store.dispatch('user/setLoginStatus', 2)
  next()
 })
 .catch(() => {
  // 失败,设置状态未登录,刷新页面
  store.dispatch('user/setLoginStatus', 0)
  location.reload()
 })
 } else {
 store.dispatch('user/setLoginStatus', 0)
 location.reload()
 }
 } else {
 // 已登录直接进入
 next()
 }
})

登录成功后存用户信息,token。访问所有的接口的时候都会在header携带token,如果token失效了,服务端会返回401,做退出操作,删除登录状态,用户信息,token,刷新页面重新进入。

request.js

// 登录超时,重新登录 
 if (res.status === 401) { 
 store.dispatch('user/fedLogOut').then(() => { 
 location.reload() 
 }) 
}

用户登录后将token和用户信息存入storage中,登录状态设置到cookie里,store user中主要是进行用户信息存贮获取删除的操作

store/modules/user.js

import { loginByCode } from '@/api/user'
import {
 saveToken,
 saveLoginStatus,
 saveUserInfo,
 removeToken,
 removeUserInfo,
 removeLoginStatus,
 loadLoginStatus,
 loadToken,
 loadUserInfo
} from '@/utils/cache'
const state = {
 loginStatus: loadLoginStatus(), // 登录状态
 token: loadToken(), // token
 userInfo: loadUserInfo() // 用户登录信息
}

const mutations = {
 SET_USERINFO: (state, userInfo) => {
 state.userInfo = userInfo
 },
 SET_LOGIN_STATUS: (state, loginStatus) => {
 state.loginStatus = loginStatus
 },
 SET_TOKEN: (state, token) => {
 state.token = token
 }
}

const actions = {
 // 登录相关,通过code获取token和用户信息
 loginWechatAuth({ commit }, code) {
 const data = {
 code: code
 }
 return new Promise((resolve, reject) => {
 loginByCode(data)
 .then(res => {
  // 存用户信息,token
  commit('SET_USERINFO', saveUserInfo(res.data.user))
  commit('SET_TOKEN', saveToken(res.data.token))
  resolve(res)
 })
 .catch(error => {
  reject(error)
 })
 })
 },
 // 设置状态
 setLoginStatus({ commit }, query) {
 if (query === 0 || query === 1) {
 // 上线打开注释,本地调试注释掉,保持信息最新
 removeToken()
 removeUserInfo()
 }
 // 设置不同的登录状态
 commit('SET_LOGIN_STATUS', saveLoginStatus(query))
 },
 // 登出
 fedLogOut() {
 // 删除token,用户信息,登陆状态
 removeToken()
 removeUserInfo()
 removeLoginStatus()
 }
}

export default {
 namespaced: true,
 state,
 mutations,
 actions
}

在根目录下.env开头的三个文件中设置微信appID

VUE_APP_WECHAT_APPID='12345678'复制代码

授权再也难不住我了,如果哪里有问题希望大家给我留言纠正,互相学习

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

Javascript 相关文章推荐
JavaScript constructor和instanceof,JSOO中的一对欢喜冤家
May 25 Javascript
使用JS+plupload直接批量上传图片到又拍云
Dec 01 Javascript
使用JQuery在线制作ppt并在线演示源码特效
Sep 08 Javascript
浅析JavaScript 调试方法和技巧
Oct 22 Javascript
基于jQuery实现响应式圆形图片轮播特效
Nov 25 Javascript
JavaScript满天星导航栏实现方法
Mar 08 Javascript
JS匿名函数和匿名自执行函数概念与用法分析
Mar 16 Javascript
微信小程序仿今日头条导航栏滚动解析
Aug 20 Javascript
微信小程序实现点击按钮后修改颜色
Dec 05 Javascript
javascript实现移动端触屏拖拽功能
Jul 29 Javascript
Vue实现返回顶部按钮实例代码
Oct 21 Javascript
JavaScript用document.write()输出换行的示例代码
Nov 26 Javascript
浅谈一种让小程序支持JSX语法的新思路
Jun 16 #Javascript
JavaScript 处理树数据结构的方法示例
Jun 16 #Javascript
JavaScript中的ES6 Proxy的具体使用
Jun 16 #Javascript
简谈创建React Component的几种方式
Jun 15 #Javascript
JS中的一些常用的函数式编程术语
Jun 15 #Javascript
JavaScript模块管理的简单实现方式详解
Jun 15 #Javascript
JavaScript工具库之Lodash详解
Jun 15 #Javascript
You might like
一致性哈希算法以及其PHP实现详细解析
2013/08/24 PHP
php使用gettimeofday函数返回当前时间并存放在关联数组里
2015/03/19 PHP
php实现从上传文件创建缩略图的方法
2015/04/02 PHP
PHP实现的折半查找算法示例
2017/12/19 PHP
Javascript miscellanea -display data real time, using window.status
2007/01/09 Javascript
JavaScript性能陷阱小结(附实例说明)
2010/12/28 Javascript
jquery表单验证使用插件formValidator
2012/11/10 Javascript
载入jQuery库的最佳方法详细说明及实现代码
2012/12/28 Javascript
js、css、img等浏览器缓存问题的2种解决方案
2013/10/23 Javascript
探讨js字符串数组拼接的性能问题
2014/10/11 Javascript
jQuery插件windowScroll实现单屏滚动特效
2015/07/14 Javascript
今天抽时间给大家整理jquery和ajax的相关知识
2015/11/17 Javascript
vue,angular,avalon这三种MVVM框架优缺点
2016/04/27 Javascript
js实现无缝循环滚动
2020/06/23 Javascript
浅谈js中的引用和复制(传值和传址)
2016/09/18 Javascript
vue如何使用 Slot 分发内容实例详解
2017/09/05 Javascript
详解React native全局变量的使用(跨组件的通信)
2017/09/07 Javascript
AngularJS实现图片上传和预览功能的方法分析
2017/11/08 Javascript
vue项目中实现的微信分享功能示例
2019/01/21 Javascript
Nuxt.js nuxt-link与router-link的区别说明
2020/11/06 Javascript
[09:34]2018DOTA2国际邀请赛寻真——永不放弃的iG
2018/08/14 DOTA
利用aardio给python编写图形界面
2017/08/21 Python
对Python Class之间函数的调用关系详解
2019/01/23 Python
快速解决pyqt5窗体关闭后子线程不同时退出的问题
2019/06/19 Python
python实现得到当前登录用户信息的方法
2019/06/21 Python
对django2.0 关联表的必填on_delete参数的含义解析
2019/08/09 Python
python中time库的实例使用方法
2019/10/31 Python
定义css设备类型-Media Queries图表简介及使用方法
2013/01/21 HTML / CSS
美国顶级水上运动专业店:Marine Products
2018/04/15 全球购物
Otticanet美国:最顶尖的世界名牌眼镜, 能得到打折季的价格
2019/03/10 全球购物
医学专业个人求职自荐信格式
2013/09/23 职场文书
大学专科生推荐信范文
2013/11/23 职场文书
社区活动策划方案
2014/08/21 职场文书
浅谈pytorch中的dropout的概率p
2021/05/27 Python
Unity连接MySQL并读取表格数据的实现代码
2021/06/20 MySQL
java项目构建Gradle的使用教程
2022/03/24 Java/Android