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

前言

本次演示采用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的控制器,比较简单就渲染一个简单的页面

1
2
3
4
5
6
7
8
9
/**
* 用户登录页
* @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库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
/**
* 获取微信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哈

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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,从文档中可以得出比较重要的就是那个回调地址

1
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登录之控制器层

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
/**
* 封装微信登录
* @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 那么对应的控制器为

1
2
3
4
5
6
7
8
9
10
/**
* 微信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});