背景
在给客户开发微信网页项目时, 目标公众号已经自主开发了项目.
微信公众号授权域名只能设置单一域名.
如果想再接入H5, 由于项目部署服务器的场景不同, 需要使用新域名访问项目.
这时微信授权登录便不能按照常规的开发步骤实现了.
实现思路
授权时, 先访问授权域名下的 html, 中转微信授权的请求, html 拿到 code 后再重定向到原网页.
而且在使用上保持和微信授权的使用方式一致.
USAGE
- 将
auth.html
部署到授权域名根目录下 - 授权时将
https://open.weixin.qq.com/connect/oauth2/authorize
替换为http[s]://{auth_domain}/auth.html
即可 - 没有了, So easy ^_^
SHOW ME THE CODE
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<script>
let options = getOptions();
let code = options.code;
if (code) {
let origin = decodeURIComponent(options.origin);
// base
let base = origin.split("?")[0];
// query
let query = getOptions(origin);
query.state = options.state;
query.code = options.code;
let queryString = Object.keys(query).map(key => key + "=" + query[key]).join("&");
// hash
let hash = "";
let hashIndex = origin.indexOf("#");
if (hashIndex > 0) hash = origin.substring(hashIndex);
// url: base+?+query+hash
let url = base + "?" + queryString + hash;
location.replace(url);
} else {
// 提取原参数
let originRedirect = options.redirect_uri;
let appId = options.appid;
let state = options.state;
// 构型重定向 url
let redirectUrl = location.href.split("?", 1)[0];
redirectUrl += "?origin=" + encodeURIComponent(originRedirect);
// 构建授权 url
let url = 'https://open.weixin.qq.com/connect/oauth2/authorize'
+ '?appid=' + appId
+ '&redirect_uri=' + encodeURIComponent(redirectUrl)
+ '&response_type=code'
+ '&scope=snsapi_userinfo'
+ '&state=' + state
+ '#wechat_redirect';
// 跳转授权
location.replace(url)
}
// 获取 url 参数
function getOptions(href) {
href = href || location.href;
let queryString = href.split('#', 1)[0].split("?", 2)[1] || "";
let options = {};
queryString.split('&')
.filter(kv => /^[^=]+=[^=]+$/.test(kv))
.forEach(kv => {
let kvArray = kv.split("=");
let key = kvArray[0];
let value = decodeURIComponent(kvArray[1]);
if (value !== "null" && value !== "undefined") {
if (!options[key]) {
options[key] = value;
} else {
if (typeof options[key] != "object") {
options[key] = [options[key]];
}
options[key].push(value);
}
}
});
return options;
}
</script>
</head>
<body>
</body>
</html>