移动互联网时代,微信、微博等超级APP是流量主要入口,而非浏览器了。因此,在微信中开发网站应用才更容易获得用户。对于前端从业者,掌握微信内网页开发技巧,不失为一种有竞争力的技能。

本文内容:如何利用微信提供的接口,实现登录功能。

技术栈

  1. 后端:php
  2. 中间层:nodejs
  3. 前端: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("/");
        });
    }  
});

流程如图:

image.png

  1. 首先,前端请求微信登录接口 /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。
image.png

  1. 然后r_pathhttps://api.myurl.com/mp/oauth (⚠️这里用后端做比较安全),通过code换取网页授权 access_tokenopenid ,并通过 access_tokenopenid 获取用户基本信息;

这部分代码由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);
        } 
}
  1. 最后,后端又重定向到 rpathhttps://www.myurl.com/wx_login ,但这次携带了 openid ,可以通过接口拿到用户的信息了;这里的做法是通过node写到cookie中token实现的。

到此,微信登录流程走完了。