现在的网站开发,都绕不开微信登录(毕竟微信已经成为国民工具)。虽然文档已经写得很详细,但是对于没有经验的开发者还是容易踩坑。
所以,专门记录一下微信网页认证的交互逻辑,也方便自己日后回查:
- 加载微信网页sdk
- 绘制登陆二维码:新tab页面绘制 / 本页面iframe绘制
- 用户扫码登陆,前端跳入回调网址
- 回调网址进一步做逻辑处理,如果是页内iframe绘制二维码,需要通知顶级页
微信网页SDK加载
在多人团队协作中,加载资源的代码需要格外小心。因为可能会有多个开发者在同一业务逻辑下调用,这会造成资源的重复加载。
处理方法有两种,第一种是对外暴露多余接口,专门check是否重复加载。但是考虑到调用者每次在加载前,都需要显式调用check()方法进行检查,难免会有遗漏。
所以采用第二种方法--设计模式中的缓存模式,代码如下:
// 备忘录模式: 防止重复加载
export const loadWeChatJs = (() => {
let exists = false; // 打点
const src = '//res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js'; // 微信sdk网址
return () => new Promise((resolve, reject) => {
// 防止重复加载
if(exists) return resolve(window.WxLogin);
let script = document.createElement('script');
script.src = src;
script.type = 'text/javascript';
script.onerror = reject; // TODO: 失败时候, 可以移除script标签
script.onload = () => {
exists = true;
resolve(window.WxLogin);
};
document.body.appendChild(script);
});
})();
绘制登陆二维码
根据《微信登陆开发指南》,将参数传递给window.WxLogin()即可。
// 微信默认配置
const baseOption = {
self_redirect: true, // true: 页内iframe跳转; false: 新标签页打开
id: 'wechat-container',
appid: 'wechat-appid',
scope: 'snsapi_login',
redirect_uri: encodeURIComponent('//1.1.1.1/'),
state: '',
};
export const loadQRCode = (option, intl = false, width, height) => {
const _option = {...baseOption, ...option};
return new Promise((resolve, reject) => {
try {
window.WxLogin(_option);
const ele = document.getElementById(_option['id']);
const iframe = ele.querySelector('iframe');
iframe.width = width"htmlcode">
componentDidMount() {
const wxOption = {
// ...
};
loadWeChatJs()
.then(WxLogin => loadQRCode(wxOption))
.catch(error => console.log(`Error: ${error.message}`));
}
回调网址与iframe通信
这一块我觉得是微信登陆交互中最复杂和难以理解的一段逻辑。开头有讲过,微信二维码渲染有2中方式,一种是打开新的标签页,另一种是在指定id的容器中插入iframe。
毫无疑问,第二种交互方式更友好,因为要涉及不同级层的页面通信,代码处理也更具挑战。
为了方便说明,请先看模拟的数据配置:
// redirect 地址会被后端拿到, 后端重定向到此地址, 前端会访问此页面
// redirect 地址中的参数, 是前端人员留给自己使用的; 后端会根据业务需要, 添加更多的字段, 然后一起返回前端
const querystr = '"color: #ff0000">前后端、微信服务器、用户端交互逻辑
按照上面的配置,我描述一下前端、用户端、微信服务器和后端交互的逻辑:
- 前端根据wxOption加载了二维码,所有信息都放在了二维码中。同时监听微信服务器的消息。
- 用户手机扫码,通知微信服务器确定登陆。
- 微信服务器接受到用户的扫码请求,转发给前端。
- 前端收到微信服务器传来消息,根据wxOption的redirect_uri参数,跳转到此url地址。注意:
- 这个接口地址是后端的,请求方式是GET
- 前端通过拼接params携带参数
- 地址会被拼接微信服务器传来的一个临时token,用于交给后端换取用户公众密钥
- 后端接收到/api/socials/weixin/authorizations${querystr}的请求,decode解码querystr中的信息。然后向微信服务端请求用户公众密钥。根绝前后端的约定(demo中用的是redirect字段),重定向到前端指定的redirect字段,并且拼接用户公众密钥等更多信息。
- 前端知悉重定向,跳到重定向的路由(demo中用的是/account/redirect)
- 在对应的路由处理后端传来的用户密钥等数据即可
- 至此,微信认证的四端交互逻辑完成
跨Iframe通信
前面流程走完了,现在的情况是页面中iframe的二维码区域,已经被替换成了/account/redirect"htmlcode">
componentDidMount() {
// ... ...
window.addEventListener('message', this.msgReceive, false);
}
componentWillUnmount() {
window.removeEventListener('message', this.msgReceive);
}
msgReceive(event) {
// 监测是否是安全iframe
if(!event.isTrusted) {
return;
}
console.log(event.data); // 获取iframe中传来的数据, 进一步进行逻辑处理
}
而在/account/redirect"htmlcode">
componentDidMount() {
// step1: 获取url中params参数
const querys = getQueryVariable(this.props.location.search);
// step2: 检查querys中的数据是否符合要求 ...
// step3: 向顶级页面传递消息
return window.parent && window.parent.postMessage('data', '*');
}
至此,微信网页认证的流程完成。
更多:关于iframe通信的更多细节,请查看MDN的文档
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
微信网页登录逻辑,微信登录逻辑
稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!
昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。
这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。
而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?
更新动态
- 小骆驼-《草原狼2(蓝光CD)》[原抓WAV+CUE]
- 群星《欢迎来到我身边 电影原声专辑》[320K/MP3][105.02MB]
- 群星《欢迎来到我身边 电影原声专辑》[FLAC/分轨][480.9MB]
- 雷婷《梦里蓝天HQⅡ》 2023头版限量编号低速原抓[WAV+CUE][463M]
- 群星《2024好听新歌42》AI调整音效【WAV分轨】
- 王思雨-《思念陪着鸿雁飞》WAV
- 王思雨《喜马拉雅HQ》头版限量编号[WAV+CUE]
- 李健《无时无刻》[WAV+CUE][590M]
- 陈奕迅《酝酿》[WAV分轨][502M]
- 卓依婷《化蝶》2CD[WAV+CUE][1.1G]
- 群星《吉他王(黑胶CD)》[WAV+CUE]
- 齐秦《穿乐(穿越)》[WAV+CUE]
- 发烧珍品《数位CD音响测试-动向效果(九)》【WAV+CUE】
- 邝美云《邝美云精装歌集》[DSF][1.6G]
- 吕方《爱一回伤一回》[WAV+CUE][454M]