h5微信本地调试 vue_vue微信授权解决方案[如何本地实现授权]
之前是自己太年轻,写什么【最终解决方案】。这一次的项目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微信授权解决方案[如何本地实现授权]相关推荐
- h5微信本地调试 vue_VUE开发微信H5页面总结
写在前面 刚入门前端的时候写过很多的微信H5页面,时隔多年感觉应该是手到擒来,不曾想竟很是费了一些功夫.现在把本次开发过程中遇到的问题以及我是如何解决的,做个记录.防止自己以后再去解决解决过的问题. ...
- (第三方平台)开发相关,解除80端口占用,微信公众号分享jssdk实现,微信开放平台登录接口接入,2022微信分享接入本地调试,微信分享定制
一.开发相关 1.平台地址 微信开放平台 QQ互联平台SDK 2.文章收集 来自CSDN兄台的QQ登录使用的教程 微信网站应用开发的详细流程和引导 VueJs单页应用实现微信网页授权及微信分享功能 [ ...
- h5微信本地调试 vue_Vue 移动端微信内H5调起支付(利用js sdk)
前端的写法 1.封装wxPay.js import wx from 'weixin-js-sdk' //先下载后引入 export function wexinPay(data) { return n ...
- h5微信本地调试 vue_Vue开发Html5微信公众号的步骤
一.调起微信支付 在微信浏览器里面打开H5网页中执行JS调起支付,WeixinJSBridge内置对象在其他浏览器中无效. (1)大致流程: (2)调用代码示例: mounted(){ if (typ ...
- 微信授权,修改本地 host
事例项目(webapck+react) 一.原理 (1)本地hosts文件,将本机ip做一个代理 本地host文件配置代理(127.0.0.1 test187.XXX.com) 表明:访问test18 ...
- 【网络工程】如何本地调试微信公众号开发教程(Nginx代理方法)
目录 前言 目的 通过Nginx代理实现本地调试微信公众号 实现工具 实现步骤 1.启动本地前端项目 2.首先配置Nginx 3.填写app.conf内容,把本地前端项目与域名形成映射. 4.把app ...
- VScode怎么开启本地服务器及本地调试?
初入职场,接触不少新鲜的东西,从最初入门的工具是HBuilder,到现在逐渐熟悉的vscode,想记录下自己的成长,不想一边学着,一边忘着.想把自己接触到的东西都记录下来吧.有需要的小伙伴,也可以参考 ...
- vue开发本地调试微信网页授权
vue开发本地调试微信网页授权 相关信息: 微信开发者工具 vue-cli3 1.修改hosts文件 这里可能会遇到无法修改的问题,可以通过修改权限或管理员权限打开修改 修改用户权限的操作如下: 修改 ...
- 如何在本地调试微信公众号授权获取code
微信网页授权要求配置授权回调页面域名,在没有域名,没有外网IP的情况下,如何在本地调试呢.下面就来介绍一下: 1.申请公众号测试账号: 注册地址:https://mp.weixin.qq.com/de ...
最新文章
- 把对像生成json并存储到文件
- 阿里巴巴分布式服务框架 Dubbo
- DotNET企业架构应用实践-企业管理软件架构的历史与发展(中)- 分布式系统
- 人工智能切入垂直领域 风口已至?
- phpfpm内存越来越高_DDR5内存规范发布
- 我对架构的理解-概念篇
- VM虚拟机下载及安装教程
- java ToStringBuilder
- SpreadJS V14.2.0 放假前Crack
- 《大师谈游戏设计——创意与节奏》【笔记一】
- WinCE下Touch Panel驱动介绍
- ShadowGun之Shader分析
- 解析域名,获得公网地址
- 小型水库雨水情测报设施建设-水库大坝水文监测
- [原创]Xilinx工具关联UEStudio
- win10 笔记本蓝牙不见了
- 加壳工具WinLicense使用教程,以v2.3.9.0为例
- 百度打不开,其它网站正常
- java enhancer_执行trace命令抛异常,Enhancer error,java.lang.ClassFormatError: null
- R语言github软件的两种安装方式