nodejs微信接入(pc扫码和mobile微信环境下)

1,144 阅读2分钟
原文链接: emufan.com

前言

本次演示采用nodejs(>7.5)+express+request框架,需要有一定的基础.
层级分为四层分别为

  • 路由层
  • 控制层
  • 请求层
  • 视图层

路由层

  • GET /login # login登录页
  • GET /login/wechat # mobile微信跳转返回页
  • GET /login/wechat-pc # pc跳转返回页

控制层

  • getLogin #对应GET /login 的控制器
  • wechatLogin #对应GET /login/wechat的控制器
  • wechatPcLogin #对应GET /login/wechat-pc的控制器

这里为getLogin的控制器,比较简单就渲染一个简单的页面

/**
 * 用户登录页
 * @param req
 * @param res
 * @return {Promise.<void>}
 */
exports.getlogin=async function (req,res) {
    res.render("jade-html/login")
};

请求层

  • getWeChatToken #获取微信AccessToken
  • getWeChatUserInfo #通过AccessToken获取用户信息

其中的rq为request-promise库

/**
 * 获取微信accesstoken     @see {@link https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842}
 * @param code            微信授权后返回的code
 * @param appid           默认为微信mobile网页登录的appid
 * @param secret          默认为微信mobile网页登录secret,
 * @return {Promise.<void>}
 */
exports.getWeChatToken=async function (code,appid=global.conf.weChatAppId,secret=global.conf.weChatSecret) {
    //https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
    let options={
        uri: `https://api.weixin.qq.com/sns/oauth2/access_token`,
        method:'get',
        qs:{
            appid,
            secret,
            code,
            grant_type:"authorization_code"
        }
    };
    return rq(options);
};
/**
 *  获取微信用户信息              @see {@link https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842}
 * @param access_token          微信的access_token
 * @param openid                微信授权后返回的openid
 * @return {Promise.<void>}
 */
exports.getWeChatUserInfo=async function (access_token,openid) {
    //https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN
    let options={
        uri: `https://api.weixin.qq.com/sns/userinfo`,
        method:'get',
        qs:{
            access_token,
            openid,
            lang:"zh_CN"
        }
    };
    return rq(options);
};

视图层

  • login.pug #login登录页

下面是视图层的代码 比较简单,自行引入jquery哈

button.js-wechat 微信登录
script.
    $(function(){
        $(".js-wechat").on('click',function(){
        if($(window).width()>420){
            //pc登录
            let srcPath=encodeURIComponent(`${window.location.origin}${window.conf.path}/login/wechat-pc`);
            let src=`https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=${srcPath}&response_type=code&scope=snsapi_login&state=STATE#wechat_redirect`;
            let $html=$(`<iframe width="400px" height="400px" target="_top" src='${src}'></iframe>`);
            $('body').append($html);
        }else{
            //mobile登录
            let currentUrl=encodeURIComponent(`${window.location.origin}${window.conf.path}/login/wechat`);
            window.location.href=`https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=${currentUrl}&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect`;
        }
}) 
    })

微信PC登录

微信PC登录一般是扫码登录,文档为微信PC登录文档

首先用户需要访问/login然后点击微信登录按钮,js做判断后直接跳转,注意pc跳转我是使用了iframe 并且特地加上了target=”_top” 这个target=top很重要.ok,从文档中可以得出比较重要的就是那个回调地址

https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=${srcPath}&response_type=code&scope=snsapi_login&state=STATE#wechat_redirect

也就是其中的redirect_uri 这里需要URI编码后才行 这里我使用的是 /login/wechat-pc, ok再来看看控制器层

微信PC登录之控制器层


/**
 * 封装微信登录
 * @param data
 * @param data.code             微信的code
 * @param data.appid            微信的appid
 * @param data.secret           微信的secret
 * @param req
 * @param res
 * @return {Promise.<void>}
 * @private
 */
async function __wechatLogin(data,req,res) {
    let {code,appid,secret}=data;
    if(!code){
        return res.redirect(`${global.conf.path}/login`);
    }
    //获取微信access,token
    let html=await userRequest.getWeChatToken(code,appid,secret);
    html=JSON.parse(html);
    let{access_token,openid}=html;
    //获取用户信息
    let wechatUserInfo=await userRequest.getWeChatUserInfo(access_token,openid);
    wechatUserInfo=JSON.parse(wechatUserInfo);
    if(!wechatUserInfo||wechatUserInfo.errcode){
        return req.redirect(`${global.conf.path}/login`)
    }
    res.redirect(`${global.conf.path}`);
}
/**
 * 微信Pc扫码登录
 * @return {Promise.<void>}
 */
exports.wechatPcLogin=async function (req,res) {
    let{query}=req;
    await __wechatLogin({code:query.code,appid:global.conf.weChatPcAppId,secret:global.conf.weChatPcSecret},req,res)
};

其中global.conf.path=””;这里只是为了方便加前缀 可以把global.conf.path设置为””就好

当用户授权后 微信会跳回刚刚填写的redirect_uri 也就是/login/wechat-pc 这时候微信跳回的地址是这样的xxx.com/login/wechat-pc?code=123456 那么拿到这个code后就可以进行accessToken的替换了,拿到accessToken后就可以获取用户权限了

微信Mobile登录

其实重点在于redirect_uri 那么对应的控制器为

/**
 * 微信mobile登录
 * @return {Promise.<void>}
 */
exports.wechatLogin=async function (req,res) {
    let{query}=req;
    await __wechatLogin({code:query.code},req,res)
};

这里我没有传递appid了 因为封装的方法默认会使用mobile的appid和secret
当授权成功后就会跳转到首页了 也就是这个 res.redirect(${global.conf.path});