移动互联网时代,微信、微博等超级APP是流量主要入口,而非浏览器了。因此,在微信中开发网站应用才更容易获得用户。对于前端从业者,掌握微信内网页开发技巧,不失为一种有竞争力的技能。
本文内容:如何利用微信提供的接口,实现登录功能。
技术栈
后端:php
中间层:nodejs
前端:react技术栈
微信登录流程
公众号配置、安全域名等具体流程微信授权登录文档已经讲的很清楚了,不再赘述。接下来主要讲怎么写代码。
第一步:配置信息
根据文档,我们知道授权微信我们需要一些配置信息,如下:
const config = {
appId: 'xxxxxxxxxxxx', // 公众号生成,安全起见,应存放到服务端
appSecrete: 'xxxxxxx', // 公众号生成,安全起见,应存放到服务端
token: 'xxxxxxxxxxxx' // 自己填写,用于验证,具体见文档
};
第二步:处理登录请求
我们使用弄的处理登录请求,代码如下:
app.use("/wx_login", (req, res, next) => {
const { query } = req
const { openid } = query
let appId = 'xxxxxxxxxxx'
if (!openid) {
const querystr = obj2Query(query),
_querystr = querystr && `${querystr}&`,
rpath = encodeURIComponent(`https://www.myurl.com/wx_login?${_querystr}`),
r_path = encodeURIComponent(`https://api.myurl.com/mp/oauth?return=${rpath}`),
r__path = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appId}&redirect_uri=${r_path}&response_type=code&scope=snsapi_base&state=authorize#wechat_redirect`;
res.redirect(r__path);
} else {
// 获取用户账户信息
fetch(`https://www.myurl.com/api/userinfo`, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
openid
})
})
.then(res => res.json())
.then(data => {
if (data.code == "1000") {
// 写入浏览器cookie,维持登录态
res.cookie("token", data.user.token, { path: "/" })
res.redirect("/")
}
})
.catch(err => {
res.redirect("/");
});
}
});
流程如图:
- 首先,前端请求微信登录接口
/wx_login
时,会被重定向到微信微信授权页面r__path
,地址:https://open.weixin.qq.com/connect/oauth2/authorize
?appid=${appId}
&redirect_uri=${r_path}
&response_type=code
&scope=snsapi_base
&state=authorize
#wechat_redirect,
获取code;
这里使用到scope是 snsapi_base
, 可以静默获取用户openid。
- 然后,
r_path
即 https://api.myurl.com/mp/oauth (⚠️这里用后端做比较安全),通过code换取网页授权access_token
和openid
,并通过access_token
和openid
获取用户基本信息;
这部分代码由php编写,我简化了很多业务逻辑,比如判断是否需要绑定手机号,是否获取到了用户信息等 等,代码如下:
<?php
public function actionOauth($code, $return = ''){
//实例化微信公众平台类
$mp = new Mp();
//获取重定向地址
$_return = $return;
//解码URL
$return = urldecode($return);
//拼接openId参数
$return .= 'openid={openid}';
//根据code获取用户信息
$userinfo = $mp->user_info((string)$code);
//提取用户OpenId
$openid = $userinfo['openid'];
//根据用户OpenId提取用户信息
$_userinfo = $mp->getUserInfo($openid);
//合并用户信息
$userinfo = array_merge($userinfo, $_userinfo);
//加密用户OpenId并替换参数
$return = str_replace('{openid}', base64_encode($openid), $return);
//查询数据库中是否存在
$wechat = Wechat::findOne(['openid' => $openid]);
// 如果不存在,添加到数据库中
if(empty($wechat)){
$wechat = New Wechat();
$wechat->add([
'openid' => $openid,
'unionid' => $unionid,
'platform' => Format::getInstance()->load('user.wechat_platform')->getKey('mp')
]);
}
if ($_return != '') {
return $this->redirect($return);
}
}
- 最后,后端又重定向到
rpath
即https://www.myurl.com/wx_login ,但这次携带了openid
,可以通过接口拿到用户的信息了;这里的做法是通过node写到cookie中token实现的。
到此,微信登录流程走完了。