一、微信开放文档
官方文档-网页授权里面有详细解释说明,若遇到问题可在微信开放社区进行咨询
网页授权流程分为四步:
1、引导用户进入授权页面同意授权,获取code
2、通过code换取网页授权access_token(与基础支持中的access_token不同)
3、如果需要,开发者可以刷新网页授权access_token,避免过期
4、通过网页授权access_token和openid获取用户基本信息(支持UnionID机制)
此次主要封装方法使用code获取到access_token,获取到网页授权access_token的同时,也获取到了openid,前端到这里最重要的也差不多就结束了。
二、方法封装
1.微信跳转授权
在vue项目 src/utils/wechatAuth.js
文件中,主要代码如下:
import { getStore, setStore } from '@/utils/util'
const qs = require('qs')
// 应用授权作用域,snsapi_base (不弹出授权页面,直接跳转,只能获取用户openid),snsapi_userinfo (弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息)
const SCOPES = ['snsapi_base', 'snsapi_userinfo']
/** * @param { string } appid 公众号的唯一标识 * @param { string } redirect_uri 授权后重定向的回调链接地址, 请使用 urlEncode 对链接进行处理 * @param { string } scope 应用授权作用域,snsapi_base (不弹出授权页面,直接跳转,只能获取用户openid),snsapi_userinfo (弹出授权页面,可通过openid拿到昵称、性别、所在地。并且, 即使在未关注的情况下,只要用户授权,也能获取其信息 ) * @param { string } state 非必须 重定向后会带上state参数,开发者可以填写a-zA-Z0-9的参数值,最多128字节 * @param #wechat_redirect 无论直接打开还是做页面302重定向时候,必须带此参数 */
class WechatAuthPlugin {
constructor() {
this.appid = null
this.redirect_uri = null
this._scope = SCOPES[0] // 授权类型,默认使用静默授权
this._code = null
this._redirect_uri = null
}
// 设置随机state参数
static makeState() {
return (
Math.random()
.toString(36)
.substring(2, 15) +
Math.random()
.toString(36)
.substring(2, 15)
)
}
// 公众号的唯一标识
setAppId(appid) {
this.appid = appid
}
/** * @description 设置授权后重定向的回调链接地址, 使用 urlEncode 对链接进行处理 * @param { * } redirect_uri 访问的redirect_uri,非必须,不传自动获取当前url */
set redirect_uri(redirect_uri) {
this._redirect_uri = encodeURIComponent(redirect_uri)
}
// 获取redirect_uri
get redirect_uri() {
return this._redirect_uri
}
/** * @description 设置授权状态 * @param { * } idx 0 - 静默授权,1 - 非静默授权 */
set scope(idx) {
this._scope = SCOPES[idx]
}
// 获取scope
get scope() {
return this._scope
}
// 获取缓存中state,否则返回默认值'STATE'
get state() {
return ['null', 'undefined', '', null, undefined].includes(getStore('wechat_auth:state')) ? 'STATE' : getStore('wechat_auth:state')
}
// state存储在缓存中
set state(state) {
setStore('wechat_auth:state', state)
}
// 设置state值
setState(value) {
this.state = value || WechatAuthPlugin.makeState()
}
/** * @description 获取引导关注着打开访问链接 */
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')
}
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`
}
// 用户同意授权,页面将跳转至 redirect_uri/?code=CODE&state=STATE,获取code参数
returnFromWechat(redirect_uri) {
const baseWithSearch = redirect_uri.split('#')[0]
let parsedUrl = ''
// 本地环境
if (process.env.NODE_ENV === 'development') {
parsedUrl = qs.parse(redirect_uri.split('?')[1])
this.state = null
this._code = parsedUrl.code
} else {
parsedUrl = qs.parse(baseWithSearch.split('?')[1])
if (parsedUrl.code) {
this._code = parsedUrl.code
}
}
}
get code() {
if (this._code === null) {
throw new Error('Not get the code from wechat server!')
}
const code = this._code
this._code = null
return code
}
/** * 处理url链接 * @returns {string} */
processUrl() {
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
}
}
const wechatAuthPlugin = new WechatAuthPlugin()
export default wechatAuthPlugin
2.封装方法引用
在vue项目 src/utils/permission.js
文件中,主要代码如下:
import router from '@/router'
import wechatAuth from '@/utils/wechatAuth'
import { getStore, setStore } from '@/utils/util'
import { CONFIG_STORAGE } from '@/utils/configs'
import API from '@/api'
// 设置APPID
const WX_APPID = 'wx12345677654321'
wechatAuth.setAppId(WX_APPID)
router.beforeEach(async (to, from, next) => {
// 授权态 0为未授权 1为授权返回code 2为使用code获取openid成功
let authStatus = getStore(CONFIG_STORAGE.AuthStatusKey) // 微信授权状态
authStatus = authStatus === null || undefined ? 0 : authStatus
switch (Number(authStatus)) {
case 0:
// 获取h5页面地址赋值给redirect_uri
wechatAuth.redirect_uri = wechatAuth.processUrl()
// 更改授权状态为1
setStore(CONFIG_STORAGE.AuthStatusKey, 1)
// 跳转到获取code访问链接
window.location.href = wechatAuth.authUrl
break
case 1: {
// 获取code值
wechatAuth.returnFromWechat(window.location.href)
const code = wechatAuth.code
// 判断code是否存在
if (!code) {
setStore(CONFIG_STORAGE.AuthStatusKey, 0)
}
// 使用cod换取eopenId
API.getWxTokenApi({code})
.then(res => {
if (res.code === '0') {
// 获取openId之后存储,并将状态更改为2
setStore(CONFIG_STORAGE.openId, res.data)
setStore(CONFIG_STORAGE.AuthStatusKey, 2)
// 对路由重定向
window.location.href = `${window.location.origin}${window.location.pathname}/${window.location.hash}`
} else {
setStore(CONFIG_STORAGE.AuthStatusKey, 0)
}
})
.catch(err => {
console.log(err)
setStore(CONFIG_STORAGE.AuthStatusKey, 0)
})
break
}
case 2:
// 若openId缺失,状态置为0,去首页重新授权
if (!getStore(CONFIG_STORAGE.openId)) {
setStore(CONFIG_STORAGE.AuthStatusKey, 0)
next('/')
} else {
next()
}
break
default:
break
}
})
详细说明
1. 设置公众号或者服务号的唯一标识AppId,直接使用wechatAuth.setAppId()
方法调用。此处使用的是静默授权,若是需要使用非静默授权调用wechatAuth.scope(1)
。此处state使用的默认值’STATE’,若是使用随机值可以调用wechatAuth.setState()
方法,可以传入参数或者内部自动生成。
const WX_APPID = 'wx12345677654321'
wechatAuth.setAppId(WX_APPID)
// 0 - 静默授权,默认值,1 - 非静默授权
//wechatAuth.scope(1)
//wechatAuth.setState('qwer1234')
//或者
//wechatAuth.setState()
2. 在全局前置守卫
中进行微信授权处理
router.beforeEach((to, from, next) => {
// ...
})
3. 授权状态的处理 authStatus
字段为微信授权态的标识,0 — 为未授权; 1 — 为授权页面跳转返回code; 2 — 为使用code获取access_token、openid成功
0 — 未授权,获取当前页面地址赋值给
wechatAuth.redirect_uri
并将存储状态更改为 1,并调用wechatAuth.authUrl
方法打开授权页面同意授权
// 获取h5页面地址赋值给redirect_uri
wechatAuth.redirect_uri = wechatAuth.processUrl()
// 更改授权状态为1
setStore(CONFIG_STORAGE.AuthStatusKey, 1)
// 跳转到授权页面同意授权
window.location.href = wechatAuth.authUrl
1 — 授权页面跳转并返回code,
wechatAuth.returnFromWechat(window.location.href)
方法对含有code的URL进行处理,wechatAuth.code
方法获取code,并且请求后端接口,获取openId
// 获取code值
wechatAuth.returnFromWechat(window.location.href)
const code = wechatAuth.code
// 判断code是否存在
if (!code) {
setStore(CONFIG_STORAGE.AuthStatusKey, 0)
}
// 使用cod换取eopenId
API.getWxTokenApi({code})
.then(res => {
if (res.code === '0') {
// 获取openId之后存储,并将状态更改为2
setStore(CONFIG_STORAGE.openId, res.data)
setStore(CONFIG_STORAGE.AuthStatusKey, 2)
// 对路由重定向
window.location.href = `${window.location.origin}${window.location.pathname}/${window.location.hash}`
} else {
setStore(CONFIG_STORAGE.AuthStatusKey, 0)
}
})
.catch(err => {
console.log(err)
setStore(CONFIG_STORAGE.AuthStatusKey, 0)
})
2 — 为使用code获取access_token、openid成功,如果有需要登录的可以在这个地方判断时候是登录态
// 若openId缺失,状态置为0,去首页重新授权
if (!getStore(CONFIG_STORAGE.openId)) {
setStore(CONFIG_STORAGE.AuthStatusKey, 0)
next('/')
} else {
// 判断是否登录,未登录时候去登录页面
if (getStore(CONFIG_STORAGE.tokenCode)) {
next()
} else {
next('/login')
}
}
3.其他方法
在vue项目 src/utils/configs.js
和src/utils/util.js
文件中,主要代码如下:
/* * @name: configs.js * @Descripttion: 定义localStorage常量 * @Author: Sando */
const CONFIG_STORAGE = {
openId: 'WX_OPENID', // 微信openId
AuthStatusKey: 'Auth-Status' // 服务号微信授权标识
}
export { CONFIG_STORAGE }
/* * @name: util.js * @Descripttion: 存储localStorage * @Author: Sando */
/** * 存储localStorage */
export const setStore = (name, content) => {
if (!name) return
if (typeof content !== 'string') {
content = JSON.stringify(content)
}
window.localStorage.setItem(name, content)
}
/** * 获取localStorage */
export const getStore = name => {
if (!name) return
return window.localStorage.getItem(name)
}
/** * 删除localStorage */
export const removeStore = name => {
if (!name) return
window.localStorage.removeItem(name)
}
/** * 清除localStorage * @param key * @returns {any} */
export const storeClear = () => {
window.localStorage.clear()
}
4.引入方法
在vue项目src/main.js
文件中引入封装好的方法,代码如下:
// 微信授权
import '@/utils/permission'
三、项目使用
按照上面介绍使用,使用 npm run serve
运行项目,这个时候在浏览器打开项目会跳转到如下链接:
页面上会出现请在微信客户端打开链接
这个时候使用微信开发者工具打开项目,调试微信网页授权 绑定为公众号开发者流程见官方文档:文档地址
若暂时在开发环境,无法正常访问,也可以在微信开发工具中Application->Local Storage中,输入WX_OPENID: 121212122
和Auth-Status:2
,暂时进行开发,环境搭建好了再上环境测试
四、写在最后
项目github地址:github.com/Sandop/WeCh… ,欢迎大家给个star,Thanks♪(・ω・)ノ
今天的文章微信公众号服务号H5前端授权方法分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/17032.html