写在前面
本次微信登录是基于vue全家桶+element-ui开发的
首先先理清楚微信网页授权登录的思路:
1,在微信开放平台注册开发者账号,并且拥有一个已审核通过的网站应用,获取相应的appid和appsecert,申请微信登录且通过审核后,就可以开始了。
2,配置微信的第三方回调域名,只有设置了回调域名,才能在扫码后微信处理完成回调到你当前的网站,在带给你code,然后在将code传给后台接受需要的消息。
3,具体的请移步官方文档网站应用微信登录功能
4,我在这里主要具体介绍在vue里边如何做这个登录的,毕竟这个我折腾了好半天,必须记录一下,方便以后学习。
接下来就是如何在vue项目中做的开发。
通过官网不难看出微信提供了两种获取扫描二维码的方式,一种是直接打开配置好的的链接,另一种是在自己的网页内渲染这个二维码。这里着重介绍在自己的网站内打开二维码的方式,这里是为了更好地用户体验。
最重要的处理是在main.js------permission.js中,处理权限的路由跳转比较谨慎,其他的直接使用微信提供的方法就好了。
第一步:在项目中vue是在index.html
引入微信的js文件
<script src="http://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js"></script>
第二步:在你需要的页面中渲染二维码
这里记录一下我踩的坑
一开始我是直接将二维码放在
el-dialog
中的,但是一直未渲染出来,所以就改为自己写了一个弹窗当你使用微信授权时候,肯定是希望在某个页面授权等微信的授权回来再跳到某个页面,这个时候就需要在该页面判断如果有code就做调用接口做你想做的操作,如果没有就走你原来页面的正常流程。
切记一点:代码注释里边有写:::当你绑定成功之后需要删除url后边的微信回调的code,如果不做处理那就在路由守卫里边一直进入这个页面,然后陷入无限的死循环。
<template>
<div v-show="Wechat_authorized_login" class="wx_dialog_toiast">
<!-- 承载二维码容器 -->
<div class="wx_dialog_toiast_delltet" id="login_container"></div>
<div class="wx_dialog_button_delete" @click="close_wchat_qrcode">
<i class="el-icon-circle-close" style="color: red; font-size: 70px"></i>
</div>
</div>
</template>
<script>
export default {
data() {
return {
Wechat_authorized_login:false,
};
},
created() {
this.Get_wechat_callback_information();
},
mounted() {
this.get_wx_qrcode(); //获取微信的登录二维码
},
methods: {
get_wx_qrcode(){
//从微信的开发文档不难看出回调域名需要经过encodeURIComponent处理
let call_back_domain_name = window.location.href,
domain_name_length = call_back_domain_name.indexOf("#") - 1,
DDNS = call_back_domain_name.substring(0, domain_name_length),
DDNS_resolution = encodeURIComponent(DDNS);
var obj = new WxLogin({
self_redirect: false,
id: "login_container", //需要承载二维码的容器id
appid: "wx795be91b97e81d8c",
scope: "snsapi_login", //网页授权,目前网页只有这一种方式,静默授权
redirect_uri: DDNS_resolution, //回调域名
state: Math.random(),
style: "white",
href: "",
});
},
// 获取微信回调信息并且绑定账号
Get_wechat_callback_information() {
let Wechat_return_code = window.location.href;
//获取微信回调的code
let wx_parseUrl = qs.parse(Wechat_return_code.split("?")[1]);
//因为这里的需求绑定账号时需要发送验证码,所以暂存本地
let wx_code_url = localStorage.getItem("QRCODEWX");
let analysis_wx_code_url = JSON.parse(wx_code_url);
//当有验证码并且微信回调了code的时候再去做绑定操作。
if (wx_parseUrl.code && wx_code_url != null) {
let parse_bind_params = {
code: wx_parseUrl.code,
codeUuid: analysis_wx_code_url.codeUuid,
codeValue: analysis_wx_code_url.codeValue,
phone: analysis_wx_code_url.phone,
};
withdrawAccountBinding(parse_bind_params).then((response) => {
this.$message({
message: response.msg,
type: "success",
center: true,
duration: "2000",
});
//绑定成功之后需要删除之前存储的验证码和验证uuid.这样方便在导航守卫里边做操作
localStorage.removeItem("QRCODEWX");
//当你绑定成功之后需要删除url后边的微信回调的code,如果不做处理那就在路由守卫里边一直进入这个页面,然后陷入无限的死循环。
if (Wechat_return_code.indexOf("?") != -1) {
Wechat_return_code = Wechat_return_code.replace(/(\?|#)[^'"]*/, "");
window.history.pushState({}, 0, Wechat_return_code);
}
//删除之后再次更新路由地址,以确保路由地址没有code。保证不会进入死循环
this.$router.replace({
path: "/agentManger/agentMoneyList",
});
this.is_show_withdraw_function(); //是否显示资金余额与提现账号
this.Obtain_withdrawal_account_number(); //首先获取提现账号的所有信息
});
}
},
},
};
</script>
<style lang='scss' scoped>
.wx_dialog_toiast {
position: fixed;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
z-index: 9854647;
background: rgba($color: #000000, $alpha: 0.5);
display: flex;
justify-content: center;
align-items: center;
.wx_dialog_toiast_delltet {
width: 500px;
height: 500px;
display: flex;
justify-content: center;
align-items: center;
}
.wx_dialog_button_delete {
position: absolute;
right: 0px;
top: 0px;
height: 100px;
width: 100px;
display: flex;
justify-content: center;
align-items: center;
}
}
</style>
第三步: main.js------permission.js在路由守卫处做处理,这里是重点
这里是做的权限处理,路由导航守卫
import router from './router'
import store from './store'
import {
Message
} from 'element-ui'
import NProgress from 'nprogress' // 页面顶部的加载进度条
import 'nprogress/nprogress.css' // progress bar style
import {
getToken
} from '@/utils/auth' // get token from cookie
import getPageTitle from '@/utils/get-page-title'
import {
getRouters
} from '@/api/user'
import {
filterAsyncRouter
} from '@/store/modules/permission'
import qs from "qs";
NProgress.configure({
showSpinner: false
}) // NProgress Configuration
const whiteList = ['/login'] // no redirect whitelist
router.beforeEach(async (to, from, next) => {
//首先拿到当前路由地址
const wx_url =window.location.href;
const parseUrl = qs.parse(wx_url.split('?')[1]);
console.log(wx_url);
var reject_url_wx = "";
var reject_code_query = parseUrl.code;
//这一步就是第二步所说的存在本地的验证码的信息,这里的操作就是如果有验证码并且有微信回调的code,那就进入当前的页面,如果没有那就进入正常的路由
let wx_code_url = localStorage.getItem("QRCODEWX");
if (wx_code_url == null) {
reject_url_wx = "";
}else{
if (parseUrl.code && parseUrl.state) {
reject_url_wx = `/agentManger/agentMoneyList?${qs.stringify(parseUrl)}`;
}else{
reject_url_wx = "";
}
}
// start progress bar
NProgress.start()
// set page title
document.title = getPageTitle(to.meta.title)
// determine whether the user has logged in
const hasToken = getToken()
if (hasToken) {
if (to.path === '/login') {
// if is logged in, redirect to the home page
next({
path: '/'
})
NProgress.done()
} else {
const hasRoles = store.getters.roles && store.getters.roles.length > 0
if (hasRoles) {
// next()
if (reject_url_wx == "") {
next();
}else{
//这里是重点,为了防止beforeach进入死循环的操作
if (to.path == "/agentManger/agentMoneyList") {
next()
}else{
next({path:'/agentManger/agentMoneyList',query:{code:reject_code_query}})
}
}
} else {
try {
store.dispatch('user/getInfo').then(res => {
loadMenus(next, to)
}).catch(err => {
console.log(err)
})
} catch (error) {
await store.dispatch('user/resetToken')
Message.error(error || 'Has Error')
next(`/login?redirect=${to.path}`)
NProgress.done()
}
}
}
} else {
/* has no token*/
if (whiteList.indexOf(to.path) !== -1) {
// in the free login whitelist, go directly
next()
} else {
// other pages that do not have permission to access are redirected to the login page.
next(`/login?redirect=${to.path}`)
NProgress.done()
}
}
})
export const loadMenus = (next, to) => {
getRouters().then(res => {
const data = res.data
const asyncRouter = filterAsyncRouter(data)
const redirectPath = asyncRouter[0].children && asyncRouter[0].children.length > 0 ?
asyncRouter[0].children[0].path :
asyncRouter[0].path
asyncRouter.unshift({
path: '/',
redirect: redirectPath,
hidden: false
})
asyncRouter.push({
path: '*',
redirect: '/404',
hidden: true
})
store.dispatch('GenerateRoutes', asyncRouter).then(() => { // 存储路由
router.addRoutes(asyncRouter) // 动态添加可访问路由表
next({
...to,
replace: true
})
})
})
}
router.afterEach(() => {
// finish progress bar
NProgress.done()
})
结束语
到此,就可以完美的做到微信扫码授权登录了,以后再也不用愁了,后续如果有变更还会更新,继续学习。
更新
这里还用到之前没用过得技术-------删除url后边的参数
let Wechat_return_code = window.location.href;
if (Wechat_return_code.indexOf("?") != -1) {
Wechat_return_code = Wechat_return_code.replace(/(\?|#)[^'"]*/, "");
window.history.pushState({}, 0, Wechat_return_code);
}