node之微信公众号开发
本文章主要介绍本人开发微信公众号历程,主要包括微信token验证,授权登陆以及用户openid和公开信息获取,微信jssdk的调用,图片上传下载等功能(请你在阅读此文之前,务必浏览一遍微信官方文档,如果没有,请点这里):
- 微信服务器token验证
- 授权登陆
- 用户openid信息获取
- 基础Access_token的获取和缓存
- 微信JSSDK、签名认证
- 素材上传下载
微信token验证
进行公众号开发的第一步,就是配置自己的服务器,并响应微信服务器的请求和验证。这些微信官方文档上都讲述的很清楚,在此不做赘叙。如果有自己的服务器,直接进行代码部署即可,如果想做测试或者自己的公众号,可以申请免费的服务器,如新浪云,七牛云等。
如下是微信服务器配置部分截图:
下面直接上代码,用于响应token验证:
app.js文件
var express = require('express');
var app = express();
var wx=require('./common/wx');
var oauth=require('./common/oauth');
var sign=require('./common/sign');
var bodyParser = require("body-parser");
var index=require('./web/webpage');
var down=require('./common/down');
//app.use(express.static(path.join(__dirname,'/web')));
var jade = require('jade');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:false}));
app.set('view engine', 'jade'); // 设置模板引擎
app.set('views', './views'); // 设置模板相对路径(相对当前目录)
app.get('/',function(req,res){
res.status(200).send('hello world');
});
app.use(express.static('./static'));
//微信服务器验证部分 !微信只支持80端口
app.get('/wxtoken', wx.sign);
//添加事件监听
app.listen(process.env.PORT || 80);
wx.js文件
//检查微信签名认证
wx.sign = function (req,res){
//hxp添加
var q = req.query||req.params;
var token =config.token; //微信token 请改成自己的
var signature = q.signature; //微信加密签名
var nonce = q.nonce; //随机数
var timestamp = q.timestamp; //时间戳
var echostr = q.echostr; //随机字符串
/*
1)将token、timestamp、nonce三个参数进行字典序排序
2)将三个参数字符串拼接成一个字符串进行sha1加密
3)开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
*/
var str = [token, timestamp, nonce].sort().join('');
var sha = sha1(str);
if (req.method == 'GET') {
if (sha == signature) {
res.send(echostr+'')
}else{
res.send('err');
}
}
else if(req.method == 'POST'){
if (sha != signature) {
return;
}
//next();
}
};
config文件,请填写自己的信息
//微信公众号配置信息
var wxconfig={
appId:"",
appSecrit:"",
token:"hxptest",//任意的token字符串 和微信服务器信息配置一致
grant_type: 'client_credential',
accessTokenUrl:'https://api.weixin.qq.com/cgi-bin/token',
ticketUrl:'https://api.weixin.qq.com/cgi-bin/ticket/getticket'
};
module.exports=wxconfig;
代码部署成功后,微信服务器配置上的URL就可填写为形如www.example.com/token,填写完其他提交即可。
以上只粘贴主要代码部分,应用在node程序之后,即可提交微信上的配置。如果配置失败,请检查你的代码。是否为token填写错误,或者node程序是否允许在80端口。正常情况,在linux环境下,node是不允许运行在80端口的,需要反向代理。
授权登陆
当需要获取用户公开信息时,要经过用户授权,继而进行相应页面跳转
等操作。
当用户授权后,会跳转到填写的url页面,并附带code参数, 该参数是获取用户openid的关键。代码如下:
oauth.js文件
/**
* Created by Administrator on 2017/1/10.
*/
var request = require('request');
var config=require('./wxconfig');
var oauth = {};
//微信用户code
oauth.pass = function (req,res){
var code = req.query.code;
//第二步:通过前台传给的code 换取微信API特殊的网页授权accesstoken 与基础接口中的token不同 两小时过期
request.get(
{
url:'https://api.weixin.qq.com/sns/oauth2/access_token?appid='+config.appId+'&secret='+config.appSecrit+'&code='+code+'&grant_type=authorization_code'
},
function(error, response, body){
if(response.statusCode == 200){
// 第三步:拉取用户信息(需scope为 snsapi_userinfo)
//console.log(JSON.parse(body));
var data = JSON.parse(body);
var access_token = data.access_token;
var openid = data.openid;
request.get(
{
url:'https://api.weixin.qq.com/sns/userinfo?access_token='+access_token+'&openid='+openid+'&lang=zh_CN'
},
function(error, response, body){
if(response.statusCode == 200){
// 第四步:根据获取的用户信息进行对应操作
var userinfo = JSON.parse(body);
//console.log(JSON.parse(body));
//console.log('获取微信信息成功!');
//t2="\<h2\>获取用户信息成功!\<\/h2\>"
// 小测试,实际应用中,可以由此创建一个帐户
/* res.send("\<h1\>hello,"+userinfo.nickname+"\<\/h1\>\
<p\>\<img src="+userinfo.headimgurl+" \/\></p>\
<p>"+userinfo.city+","+userinfo.province+","+userinfo.country+"</p>\
");
*/
var data_info={};
data_info.subscribe=true;
data_info.user_nickname=userinfo.nickname;
data_info.user_address=userinfo.city+","+userinfo.province+","+userinfo.country;
data_info.user_sex=userinfo.sex;
data_info.user_headurl=userinfo.headimgurl;
res.send(JSON.stringify(data_info));//将微信服务器数据鸳鸯返回给客户端
//数据库操作等 复杂的情况 包括刷新token 缓存token 等
//根据openid 查询bx_wx:u_info,更新用户信息
updateU_info(openid,userinfo);
}else{
console.log(response.statusCode);
res.send('{msg:"failed",code:'+response.statusCode+'}');
}
}
);
}else{
console.log(response.statusCode);
res.send('{msg:"failed",code:'+response.statusCode+'}');
}
}
);
//code换取用户open信息 存入redis数据库中 以备不时之需
function updateU_info(openid,u_info){
//openid和用户信息存入redis
var client=require('../db/db_config');
client.hget("bx_wx:u_info",openid,function(err,response){
console.log(err,response);
if(!err){
if(response){
console.log("update user info");
var data=JSON.parse(response);
if(data.subscribe){
data.subscribe=true;
data.user_nickname=u_info.nickname;
data.user_address=u_info.city+","+u_info.province+","+u_info.country;
data.user_sex=u_info.sex;
data.user_headurl=u_info.headimgurl;
client.hset("bx_wx:u_info",openid,JSON.stringify(data),function(err,response){
console.log(err,response);
});
}else{
return;
}
}else{
console.log("something is wrong,not normal:at openid get and update user msg");
}
}
});
}
};
module.exports = oauth;
用户openid获取
其实用户信息获取,在上一步“授权登陆”中已经有相关代码了,
代码中第四步;