准备工作 大致流程
网站应用微信登录是基于OAuth2.0协议标准构建的微信OAuth2.0授权登录系统。 在进行微信OAuth2.0授权登录接入之前,在微信开放平台注册开发者帐号,并拥有一个已审核通过的网站应用,并获得相应的 AppID 和AppSecret,申请微信登录且通过审核后,可开始接入流程
生成二维码
微信扫码后跳转过程
步骤1
mounted() {
// 注册全局登录事件对象
window.loginEvent = new Vue();
// 监听登录事件
loginEvent.$on("loginDialogEvent", function () {
document.getElementById("loginDialog").click();
});
// 触发事件,显示登录层:loginEvent.$emit('loginDialogEvent')
//初始化微信js
const script = document.createElement("script");
script.type = "text/javascript";
script.src =
"https://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js";
document.body.appendChild(script);
},
步骤2
weixinLogin() {
this.dialogAtrr.showLoginType = "weixin";
weixinApi.getLoginParam().then((response) => {
var obj = new WxLogin({
self_redirect: true,
id: "weixinLogin", // 需要显示的容器id
appid: response.data.appid, // 公众号appid wx*******
scope: response.data.scope, // 网页默认即可
redirect_uri: response.data.redirectUri, // 授权成功后回调的url
state: response.data.state, // 可设置为简单的随机数加session用来校验
style: "black", // 提供"black"、"white"可选。二维码的样式
href: "", // 外部css文件url,需要https
});
});
},
在前端中需要在微信登录的事件中实例化以上js对象如上图、
下面是后端生成二维码的接口,功能是返回生成二维码所需要的参数
@GetMapping("getLoginParam")
@ResponseBody
//1 生成微信扫描二维码,返回生成二维码需要的参数
public Result genQrConnect(HttpSession session) throws UnsupportedEncodingException {
String redirectUri = URLEncoder.encode(ConstantWxPropertiesUtil.WX_OPEN_REDIRECT_URL, "UTF-8");
Map<String, Object> map = new HashMap<>();
map.put("appid", ConstantWxPropertiesUtil.WX_OPEN_APP_ID);
map.put("redirectUri", redirectUri);
map.put("scope", "snsapi_login");
map.put("state", System.currentTimeMillis()+"");//System.currentTimeMillis()+""
return Result.ok(map);
}
回调方法,获取扫码人的信息
通过code(微信端的临时票据)加上appid和appsecret换取微信方的access_token返回给第三方平台
httpclient
httpclient是用来得到地址/接口返回的数据,模拟浏览器请求和响应的过程。
accesstokenInfo:
{“access_token”:“57_izfuhrY5sBe69Y0Z9aMdBaZU3XAD7nmK71KaT8YQwFJKa7uRJKJYuoiCElq-Md0AaOAyE5OjpXD1qV0I90311UAdqwATtzVSupcRirOOq20”,
“expires_in”:7200,
“refresh_token”:“57_2LgxhJSd6QofM3MW5a3tL8uKEp2at5Ke3RDDUcJF3-1X3YhpPjja4dEiYcR6OPLMqGRaT8RTZTuUTL4VNvMDVQku6Lt_eNVE4beoOt1Ipbw”,
“openid”:“o3_SC53LCi1Pj5hNbkrOBtCWwF-E”,
“scope”:“snsapi_login”,
“unionid”:“oWgGz1MDFPzvTMIRa9_SrU55hzJU”}
access_token:访问凭证
openid是我的微信的唯一标识
resultInfo:
{“openid”:“o3_SC53LCi1Pj5hNbkrOBtCWwF-E”,
“nickname”:“虚虚”,
“sex”:0,
“language”:“”,
“city”:“”,
“province”:“”,
“country”:“”,
“headimgurl”:“https://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTLWYYlfOvE9ibOY2R7znzlwyWib9ZdwW9vQUXT671AMsFfVzuaibFVuTjibHz5M3qBU710shouDricJLIQ/132”,
“privilege”:[],
“unionid”:“oWgGz1MDFPzvTMIRa9_SrU55hzJU”}
扫码完成后回调时重定向到前端的/weixin/callback.vue
在callback.vue中
mounted() {
let token = this.$route.query.token
let name = this.$route.query.name
let openid = this.$route.query.openid
// 调用父vue方法
window.parent['loginCallback'](name, token, openid)
}
三个参数传过来后,在header.vue中,会调用当前页面的self.loginCallback
mounted() {
// 注册全局登录事件对象
window.loginEvent = new Vue();
// 监听登录事件
loginEvent.$on("loginDialogEvent", function () {
document.getElementById("loginDialog").click();
});
// 触发事件,显示登录层:loginEvent.$emit('loginDialogEvent')
//初始化微信js
const script = document.createElement("script");
script.type = "text/javascript";
script.src =
"https://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js";
document.body.appendChild(script);
// 微信登录回调处理
let self = this;
window["loginCallback"] = (name,token, openid) => {
self.loginCallback(name, token, openid);
}
微信登录强制手机号绑定
-
微信扫码登录后,会返回给前端openid值,而这个openid在后端中已经判断,如果有手机号,openid=“”。
-
前端判断当openid不为空时,说明要绑定手机号,就调用手机号登录的方法this.showLogin()
-
showLogin() 方法将弹出框参数设置为true,this.dialogUserFormVisible = true,所以弹出登录框进行手机号登录
-
后端的手机登录接口中,是否已经微信登录过,如果微信登录过,则通过openid拿到对应的userinfo,进行手机号绑定,如果没有微信登录过,则依旧按照手机登录的流程。