【开发心得】微信网页应用授权登录
微信登录官方资料:
第三方参考资料:
vue 微信扫码登录嵌入方式及开发踩的坑点_范特西是只猫的博客-CSDN博客_微信网页扫码登录开发文档
说明:
1. 微信官方有两种对外能力,分别是 网站应用 与 微信开放平台,这两个服务都有授权登录,注意,我们使用的是前者,故需要的scope 是
snsapi_login. 而微信开放平台是供给小程序,公众号等使用的。权限是snsapi_base 和 snsapi_userinfo
网站应用: 需要300块开通费用与企业授权。
开放平台: 需要申请开发者账号及授权,并且提供测试账号。
2. 微信登录对接方式有两种
(1) 直接根据appid与scope等新开一个网页,很多网站都使用该方案,缺点: 需要弹出一个单独的页面,用户体验不够友好。
(2) 嵌入方式。优点,充分自定义。缺点: 对接比较繁琐。
对接步骤:
参数详解(具体以官方为准):
appid 应用id,微信接入申请时获得 scope:权限范围 默认snsapi_login state: 自定义状态保持 login_tupe: jssdk stype: "black"、"white"可选,默认为黑色文字描述 self_redirect: true:手机点击确认登录后可以在 iframe 内跳转到 redirect_uri,false:手机点击确认登录后可以在 top window 跳转到 redirect_uri。默认为 false。 redirect_uri: 重定向地址,需要进行UrlEncode href: 自定义样式链接,第三方可根据实际需求覆盖默认样式 注意: 1. href base64加密后的样式 2. redirect_uri 参数错误 申请时,配置的重定向域名和当前使用域名不一致,或者scope不对. (3). 创建一个单独的direct页面,回调用
修改route.js 增加
{ path: '/oauth', meta: {title: "登录跳转", noCache: true}, component: () => import('@/views/oauth'), hidden: true, },路由控制,放行该路由白名单:
const whiteList = ['/login', '/oauth']; // no redirect whitelist
direct页面
<template>
<div>
<div class="loader">授权中...</div>
</div>
</template>
<script>
export default {
name: "oauth",
data() {
return {
loading: true,
}
},
mounted() {
let code = this.$route.query.code;
let bindState = this.$route.query.state;
let wechatInfo = {
code,
bindState
}
window.parent.postMessage(wechatInfo, '*');
},
methods: {
}
}
</script>
<style scoped>
body{
background: #56b4ab;
}
.loader,
.loader:before,
.loader:after {
background: #FFF;
/*
* load1:执行的动画名
* 1s:执行一秒
* infinite:执行无限次
* ease-in-out:动画以低速开始和结束
*/
animation: load1 1s infinite ease-in-out;
width: 1em;
height: 4em;
}
.loader:before,
.loader:after {
position: absolute;
top: 0;
content: '';
}
.loader:before {
left: -1.5em;
}
.loader {
text-indent: -9999em;
margin: 40% auto;
position: relative;
font-size: 11px;
/* 延时0.16s */
animation-delay: 0.16s;
}
.loader:after {
left: 1.5em;
/* 延时0.32s */
animation-delay: 0.32s;
}
@keyframes load1 {
0%,
80%,
100% {
box-shadow: 0 0 #FFF;
height: 4em;
}
40% {
/* 实现上部拉伸 */
box-shadow: 0 -2em #ffffff;
/* 实现下部拉伸 */
height: 5em;
}
}
</style>
direct页面获取重定向后携带的code和自定义状态,发送消息给父页面
mounted() {
let code = this.$route.query.code;
let bindState = this.$route.query.state;
let wechatInfo = {
code,
bindState
}
window.parent.postMessage(wechatInfo, '*');
}
父页面监听:
mounted: function () {
// 开启微信登录
if (this.useWechatLogin) {
window.addEventListener('message', this.receiveMessage);
}
this.loginUsernamePassword();
},
destroyed() {
window.removeEventListener('message', this.receiveMessage);
}
二维码核心页面:
<template>
<div>
<iframe sandbox="allow-scripts allow-top-navigation allow-same-origin" scrolling="no" width="500" height="300" frameBorder="0"
allowTransparency="true" :src="setSrc" ref="iframe" v-if="showIframe"></iframe>
<!-- <iframe sandbox="allow-scripts allow-top-navigation" scrolling="no" width="500" height="300" frameBorder="0" allowTransparency="true" :src="setSrc"></iframe>-->
</div>
</template>
<script>
export default {
methods: {
},
data () {
return {
// src: 'https://open.weixin.qq.com/connect/qrconnect?appid=wxe1f5def243e0390b&scope=snsapi_login&redirect_uri=https://abstest.tenpay.com/abs/author/callBack.do&state=0001&login_type=jssdk&self_redirect=default&style=black&href=./wx.css',
// https://open.weixin.qq.com/connect/qrconnect?appid=wxe1f5def243e0390b&scope=undefined&redirect_uri=undefined&state=&login_type=jssdk&self_redirect=default&style=black&href=
}
},
computed : {
setSrc () {
var _url = 'https://open.weixin.qq.com/connect/qrconnect?appid='+ this.appid
// var _url = 'https://open.weixin.qq.com/connect/qrconnect?appid='+ this.appid
+ '&scope=' + this.scope
+ '&redirect_uri=' + this.redirect_uri
+ '&state=' + this.state
+ '&login_type=' + this.login_type
+ '&style=' + this.theme
+ '&self_redirect=' + this.self_redirect
+ '&href=' + this.href;
return _url;
},
},
props:{
//应用唯一标识,在微信开放平台提交应用审核通过后获得
appid : String,
//应用授权作用域,拥有多个作用域用逗号(,)分隔,网页应用目前仅填写snsapi_login即可
scope : String,
//重定向地址,需要进行UrlEncode
redirect_uri : String,
//用于保持请求和回调的状态,授权请求后原样带回给第三方。该参数可用于防止csrf攻击(跨站请求伪造攻击),建议第三方带上该参数,可设置为简单的随机数加session进行校验
state : {
type : String,
default: ''
},
//提供"black"、"white"可选,默认为黑色文字描述。详见文档底部FAQ
theme : {
type : String,
default: 'black'
},
// 自定义样式链接,第三方可根据实际需求覆盖默认样式。详见文档底部FAQ
href : {
type : String,
default: ''
},
// true:手机点击确认登录后可以在 iframe 内跳转到 redirect_uri,false:手机点击确认登录后可以在 top window 跳转到 redirect_uri。默认为 false。
self_redirect : {
type : Boolean,
default: true
},
// sdk的扩展字符串,但是在这里就默认了jssdk,暂时不建议修改
login_type : {
type : String,
default: 'jssdk'
},
showIframe: {
type: Boolean,
default: true
}
},
}
</script>
测试:
1. 直接部署测试。如果有条件的话。
2. 本地映射成申请时候填写的域名。 百度搜索 Windows hosts修改,或者 Mac host修改。根据开发环境来。(测试服务器也类似)
3. 如果后台登记的是https服务的话,本地webpack需要做下配置:
https 开启 并且设置为跨域.
vue.config.js
devServer: {
port: 443,
hot: true,
disableHostCheck: true,
https: true,
proxy: {
'/api': { // 凡是接口中后面域名中带有api的 , 框架都会进行一个代理转发
target: 'http://xxxxxx/api', // 后端提供的接口地址
changeOrigin: true, // 开启跨域代理
}
}
},
相信完整的看完本文,应该就能完成了,不方便公开全部代码,有问题欢迎私信交流讨论。