之前是自己太年轻,写什么【最终解决方案】。这一次的项目vue移动端电商项目,做了很多的优化。大家都知道授权需要每次都要发布到线上,本地的需要代理,这让我们很头疼。后面会介绍一个本地直接授权的方式,真的超级香。

时隔几年,第三次升级我的微信授权,每一次思路都更加清晰,当我的知识越来越广,越来越深,我相信会有第四次,第五次。。。

另外也优化:

微信分享

keep-alive返回到上次浏览的位置

vue-router 所有页面携带参数

...

后续会持续分享,接下来首先优化的就是授权逻辑的优化。

场景

整个项目无论什么页面进入都需要进行授权,一般微信公众号H5项目这一点都是需要做到

接下来我们开始吧,先克隆安装依赖,不要着急启动,先把准备工作做好。

// 克隆项目

git clone https://github.com/sunnie1992/vue-wechat-auth.git

//安装依赖

npm install 复制代码

实现本地微信授权

1.工具

实现本地开发授权,你需要使用微信开发者工具,网页是没有办法直接本地拿到授权的。

2.将auth.html部署到服务器上

这里我们用到了 GetWeixinCode ,使用的时候修复了一些bug

携带的参数在授权完之后没能全部带回来。

hash回调url错误问题

部署auth.html(在github项目的根目录下)到你的微信授权回调域名的目录下。

前往微信公众平台->接口权限->网页授权获取用户基本信息->修改,填写授权回调页面域名,例如www.abc.com

在www.abc.com域名下部署auth.html,不一定是根目录,例如:https://www.abc.com/xxx/auth....

微信登录

var GWC = {

version: '1.2.0',

urlParams: {},

appendParams: function (url, params) {

if (params) {

var baseWithSearch = url.split('#')[0];

var hash = window.location.hash.split('#')[1];

if (hash) {

baseWithSearch = baseWithSearch + '#' + hash;

}

for (var key in params) {

var attrValue = params[key];

if (attrValue !== undefined) {

var newParam = key + "=" + attrValue;

if (baseWithSearch.indexOf('?') > 0) {

var oldParamReg = new RegExp('^' + key + '=[-%.!~*\'\(\)\\w]*', 'g');

if (oldParamReg.test(baseWithSearch)) {

baseWithSearch = baseWithSearch.replace(oldParamReg, newParam);

} else {

baseWithSearch += "&" + newParam;

}

} else {

baseWithSearch += "?" + newParam;

}

}

}

}

return baseWithSearch;

},

getUrlParams: function() {

var pairs = location.search.substring(1).split('&')

for (var i = 0; i < pairs.length; i++) {

var pos = pairs[i].indexOf('=')

if (pos === -1) {

continue

}

GWC.urlParams[pairs[i].substring(0, pos)] = decodeURIComponent(pairs[i].substring(pos + 1))

}

},

doRedirect: function() {

var code = GWC.urlParams['code']

var appId = GWC.urlParams['appid']

var scope = GWC.urlParams['scope'] || 'snsapi_base'

var state = GWC.urlParams['state']

var isMp = GWC.urlParams['isMp'] //isMp为true时使用开放平台作授权登录,false为网页扫码登录

var baseUrl

var redirectUri

if (!code) {

baseUrl = 'https://open.weixin.qq.com/connect/oauth2/authorize#wechat_redirect'

if (scope == 'snsapi_login' && !isMp) {

baseUrl = 'https://open.weixin.qq.com/connect/qrconnect'

}

//第一步,没有拿到code,跳转至微信授权页面获取code

redirectUri = GWC.appendParams(baseUrl, {

appid: appId,

redirect_uri: encodeURIComponent(location.href),

response_type: 'code',

scope: scope,

state: encodeURIComponent(state)

})

} else {

const params = Object.assign({}, GWC.urlParams)

delete params.backUrl

//第二步,从微信授权页面跳转回来,已经获取到了code,再次跳转到实际所需页面

redirectUri = GWC.appendParams(GWC.urlParams['backUrl'], params)

}

location.href = redirectUri

}

}

GWC.getUrlParams()

GWC.doRedirect()

3.实现代码逻辑

主要文件:src/plugins/wechatAuth.js

微信授权相关方法封装这里引用的是[vue-wechat-login],做了简单的修改,直接在路由钩子文件permission.js使用。

const qs = require('qs')

// 应用授权作用域,snsapi_base (不弹出授权页面,直接跳转,只能获取用户openid),snsapi_userinfo (弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息)

const SCOPES = ['snsapi_base', 'snsapi_userinfo']

class VueWechatAuthPlugin {

constructor() {

this.appid = null

this.redirect_uri = null

this.scope = SCOPES[1]

this._code = null

this._redirect_uri = null

}

static makeState() {

return (

Math.random()

.toString(36)

.substring(2, 15) +

Math.random()

.toString(36)

.substring(2, 15)

)

}

setAppId(appid) {

this.appid = appid

}

set redirect_uri(redirect_uri) {

this._redirect_uri = encodeURIComponent(redirect_uri)

}

get redirect_uri() {

return this._redirect_uri

}

get state() {

return localStorage.getItem('wechat_auth:state')

}

set state(state) {

localStorage.setItem('wechat_auth:state', state)

}

get authUrl() {

if (this.appid === null) {

throw new Error('appid must not be null')

}

if (this.redirect_uri === null) {

throw new Error('redirect uri must not be null')

}

this.state = VueWechatAuthPlugin.makeState()

return `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`

}

returnFromWechat(redirect_uri) {

const parsedUrl = qs.parse(redirect_uri.split('?')[1])

if (process.env.NODE_ENV === 'development') {

this.state = null

this._code = parsedUrl.code

} else {

if (this.state === null) {

throw new Error("You did't set state")

}

if (parsedUrl.state === this.state) {

this.state = null

this._code = parsedUrl.code

} else {

this.state = null

throw new Error(`Wrong state: ${parsedUrl.state}`)

}

}

}

get code() {

if (this._code === null) {

throw new Error('Not get the code from wechat server!')

}

const code = this._code

this._code = null

// console.log('code: ' + code)

return code

}

}

const vueWechatAuthPlugin = new VueWechatAuthPlugin()

export default vueWechatAuthPlugin

4.设置相关变量

在开发之前你要首先在下面三个文件设置两个变量,如果你已经启动项目,设置后需要重启。

.env.development

.env.staging

.env.production

VUE_APP_WECHAT_APPID是你的appid,在.env.[环境] 文件中设置

VUE_APP_WECHAT_AUTH_URL是你的auth.html 访问地址。在.env.[环境] 文件中设置

5.permission.js 路由守卫

设置授权白名单whiteList,授权失败,或者其他错误进入404页面。

// 设置回调地址,本地和线上不同

wechatAuth.redirect_uri = processUrl()

await store.dispatch('user/setLoginStatus', 1)

// 跳转完整的授权地址

window.location.href = wechatAuth.authUrl复制代码

wechatAuth.authUrl 地址 https://open.weixin.qq.com/co..._uri 设置调用 processUrl方法,本地开发,回调设置本地路径会报redirect_uri错误,所以我们跳到中间页auth.html再携带code跳会到backUrl。

本地环境返回授权的回调地址:

`${process.env.VUE_APP_WECHAT_AUTH_URL}?backUrl=${window.location.href}`复制代码

其中 process.env.VUE_APP_WECHAT_AUTH_URL 就是中间授权页面的网址。backUrl后面跟的是你本地开发的地址。

线上环境返回的是正常的微信授权地址:

redirect_uri是线上的地址,不用中间页跳转。

import qs from 'qs'

import router from '@/router'

import store from '@/store'

import wechatAuth from '@/plugins/wechatAuth'

// 设置APPID

wechatAuth.setAppId(process.env.VUE_APP_WECHAT_APPID)

const whiteList = ['/404']

router.beforeEach(async (to, from, next) => {

// 在白名单,直接进入

if (whiteList.indexOf(to.path) !== -1) {

return next()

}

const {loginStatus} = store.getters

switch (Number(loginStatus)) {

case 0:

// 获取跳转地址

wechatAuth.redirect_uri = processUrl()

await store.dispatch('user/setLoginStatus', 1)

window.location.href = wechatAuth.authUrl

break

case 1:

try {

wechatAuth.returnFromWechat(to.fullPath)

const code = wechatAuth.code

console.log('code==', code)

// 通过code换取token

// await store.dispatch('user/loginWechatAuth', code)

await store.dispatch('user/setLoginStatus', 2)

next()

} catch (err) {

await store.dispatch('user/setLoginStatus', 0)

next('/404')

}

break

case 2:

next()

break

default:

break

}

})

/**

* 处理url链接

* @returns {string}

*/

function processUrl() {

// 本地环境换通过auth.html拿code

if (process.env.NODE_ENV === 'development') {

// 中间授权页地址

return `${process.env.VUE_APP_WECHAT_AUTH_URL}?backUrl=${window.location.href}`

}

const url = window.location.href

// 解决多次登录url添加重复的code与state问题

const urlParams = qs.parse(url.split('?')[1])

let redirectUrl = url

if (urlParams.code && urlParams.state) {

delete urlParams.code

delete urlParams.state

const query = qs.stringify(urlParams)

if (query.length) {

redirectUrl = `${url.split('?')[0]}?${query}`

} else {

redirectUrl = `${url.split('?')[0]}`

}

}

return redirectUrl

}

当配置好参数,本地启动后,可以正常进入授权页面

// 启动

npm run serve 复制代码

同意之后就看到code值了

到此主要的流程就结束了。当授权成功后需要通过code换取token,因为并没有对接后台,所以这里我注释掉了

接下来操作在vuex中进行,用户根据需求对接后台接口即可。

/src/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

}

utils/cache.js文件用户来缓存数据

import cookies from 'js-cookie'

import storage from 'good-storage'

const LoginStatusKey = 'Login-Status' // 登录态 0未授权未登录 1授权未登录 2 登陆成功

const TokenKey = 'Access-Token' // token

const UserInfoKey = 'User-Info' // 用户信息 {} {...}

// 获取登录状态

export function loadLoginStatus() {

return cookies.get(LoginStatusKey) || 0

}

// 保持登录状态

export function saveLoginStatus(status) {

cookies.set(LoginStatusKey, status, {expires: 7})

return status

}

// 删除登录状态

export function removeLoginStatus() {

cookies.remove(LoginStatusKey)

return ''

}

// 获取token

export function loadToken() {

return storage.get(TokenKey, '')

}

// 保存token

export function saveToken(token) {

storage.set(TokenKey, token)

return token

}

// 删除token

export function removeToken() {

storage.remove(TokenKey)

return ''

}

// 获取用户信息

export function loadUserInfo() {

return storage.get(UserInfoKey, {})

}

// 保存用户信息

export function saveUserInfo(userInfo) {

storage.set(UserInfoKey, userInfo)

return userInfo

}

// 删除用户信息

export function removeUserInfo() {

storage.remove(UserInfoKey)

return {}

}

项目地址

另外,项目架构介绍请看[ vue-h5-template]基于vue-cli4.0+webpack 4+vant ui + sass+ rem适配方案+axios封装。如果你只需要授权逻辑,只要把涉及到的相关文件放到你的项目下就可以。

关于我

如果您遇到了问题可以给我提issues

您也可以扫描添加下方的微信并备注 Sol 加前端交流群,交流学习。

如果对你有帮助送我一颗小星星,你的star是我前进的动力(づ ̄3 ̄)づ╭❤~

h5微信本地调试 vue_vue微信授权解决方案[如何本地实现授权]相关推荐

  1. h5微信本地调试 vue_VUE开发微信H5页面总结

    写在前面 刚入门前端的时候写过很多的微信H5页面,时隔多年感觉应该是手到擒来,不曾想竟很是费了一些功夫.现在把本次开发过程中遇到的问题以及我是如何解决的,做个记录.防止自己以后再去解决解决过的问题. ...

  2. (第三方平台)开发相关,解除80端口占用,微信公众号分享jssdk实现,微信开放平台登录接口接入,2022微信分享接入本地调试,微信分享定制

    一.开发相关 1.平台地址 微信开放平台 QQ互联平台SDK 2.文章收集 来自CSDN兄台的QQ登录使用的教程 微信网站应用开发的详细流程和引导 VueJs单页应用实现微信网页授权及微信分享功能 [ ...

  3. h5微信本地调试 vue_Vue 移动端微信内H5调起支付(利用js sdk)

    前端的写法 1.封装wxPay.js import wx from 'weixin-js-sdk' //先下载后引入 export function wexinPay(data) { return n ...

  4. h5微信本地调试 vue_Vue开发Html5微信公众号的步骤

    一.调起微信支付 在微信浏览器里面打开H5网页中执行JS调起支付,WeixinJSBridge内置对象在其他浏览器中无效. (1)大致流程: (2)调用代码示例: mounted(){ if (typ ...

  5. 微信授权,修改本地 host

    事例项目(webapck+react) 一.原理 (1)本地hosts文件,将本机ip做一个代理 本地host文件配置代理(127.0.0.1 test187.XXX.com) 表明:访问test18 ...

  6. 【网络工程】如何本地调试微信公众号开发教程(Nginx代理方法)

    目录 前言 目的 通过Nginx代理实现本地调试微信公众号 实现工具 实现步骤 1.启动本地前端项目 2.首先配置Nginx 3.填写app.conf内容,把本地前端项目与域名形成映射. 4.把app ...

  7. VScode怎么开启本地服务器及本地调试?

    初入职场,接触不少新鲜的东西,从最初入门的工具是HBuilder,到现在逐渐熟悉的vscode,想记录下自己的成长,不想一边学着,一边忘着.想把自己接触到的东西都记录下来吧.有需要的小伙伴,也可以参考 ...

  8. vue开发本地调试微信网页授权

    vue开发本地调试微信网页授权 相关信息: 微信开发者工具 vue-cli3 1.修改hosts文件 这里可能会遇到无法修改的问题,可以通过修改权限或管理员权限打开修改 修改用户权限的操作如下: 修改 ...

  9. 如何在本地调试微信公众号授权获取code

    微信网页授权要求配置授权回调页面域名,在没有域名,没有外网IP的情况下,如何在本地调试呢.下面就来介绍一下: 1.申请公众号测试账号: 注册地址:https://mp.weixin.qq.com/de ...

最新文章

  1. 把对像生成json并存储到文件
  2. 阿里巴巴分布式服务框架 Dubbo
  3. DotNET企业架构应用实践-企业管理软件架构的历史与发展(中)- 分布式系统
  4. 人工智能切入垂直领域 风口已至?
  5. phpfpm内存越来越高_DDR5内存规范发布
  6. 我对架构的理解-概念篇
  7. VM虚拟机下载及安装教程
  8. java ToStringBuilder
  9. SpreadJS V14.2.0 放假前Crack
  10. 《大师谈游戏设计——创意与节奏》【笔记一】
  11. WinCE下Touch Panel驱动介绍
  12. ShadowGun之Shader分析
  13. 解析域名,获得公网地址
  14. 小型水库雨水情测报设施建设-水库大坝水文监测
  15. [原创]Xilinx工具关联UEStudio
  16. win10 笔记本蓝牙不见了
  17. 加壳工具WinLicense使用教程,以v2.3.9.0为例
  18. 百度打不开,其它网站正常
  19. java enhancer_执行trace命令抛异常,Enhancer error,java.lang.ClassFormatError: null
  20. R语言github软件的两种安装方式

热门文章

  1. 二叉树深度优先搜索算法
  2. 一道初等平面几何竞赛题的暴力解法
  3. hadoop-common源码分析之-Configuration
  4. 你不知道的redis三-Redis的持久化机制
  5. oppo手机微信支付成功后回调不执行的处理办法
  6. ImmunoChemistry艾美捷自噬试验,红色解决方案
  7. Java项目:在线嘿嘿网盘系统设计和实现(java+Springboot+ssm+mysql+maven)
  8. Redis学习(二)----性能测试
  9. git笔记(一)git版本管理
  10. YUV和RGB的相互转换实验