node-wechat 微信實踐
node-wechat
從去年開始微信開發越來越火了,體現在sdk和h5上(h5如果大家想聽,可以回復),這里就簡單介紹一下sdk開發
既然是noder,那肯定要用nodejs寫,不然會被鄙視的。
node-webot簡介
node-webot是老樸幾個人建的org,主要開發微信sdk相關的node modules
地址 https://github.com/node-webot/
- wechat 微信公共平臺消息接口服務中間件
- weixin-robot 微信公共帳號自動回復機器人 A Node.js robot for wechat.
- wechat-oauth 授權
- wechat-api Wechat API/主動調用API </ul>
- wechat-oauth
- wechat-api(菜單,消息回復等)
- wx_jsapi_sign(js-sdk) </ul>
wechat sdk開發常用包
創建菜單
wxapi.js
var API = require('wechat-api'); var config = require('config');var menu_config = config.get('wx.wx_menu'); var app_id = config.get('wx.app_id'); var app_secret = config.get('wx.app_secret');
//配置 var api = new API(app_id, app_secret);
//測試 function app(){ api.createMenu(menu_config, function(err, result){ console.log(result); }); }
module.exports = app;</pre>
把數據放到配置文件中
config/default.json
{ "domain": "xxxxxxxx.com", "is_debug": true, "mongodb": { "host": "127.0.0.1", "port": "27017", "db": "node-webot" }, "sms": { "host": "127.0.0.1", "port": "5001" }, "wx": { "app_id": "wx04014b02asdsfdsfsf", "app_secret": "cc4c224b50fkjlksdafkldfsakljsdfk", "wx_menu": { "button": [ { "name": "菜單", "sub_button": [ { "type": "view", "name": "資訊菜單", "url": "http://ip:port/all" } ] }, { "name": "菜單2", "sub_button": [ { "type": "view", "name": "我的11", "url": "http://ip:port/all" } ] }, { "name": "助理", "sub_button": [ { "type": "view", "name": "大學", "url": "http://ip:port/all" }, { "type": "view", "name": "社區", "url": "http://ip:port/all" } ] } ] } } }
oauth
使用微信的用戶,或者綁定微信賬號
微信有一個唯一的id是openid,它是辨別的唯一標識。
routes/weixin.js
// 微信授權和回調 var client = new OAuth(app_id, app_secret);// 主頁,主要是負責OAuth認真 router.get('/', function(req, res) { var url = client.getAuthorizeURL('http://' + domain + '/weixin/callback','','snsapi_userinfo'); res.redirect(url) })
/**
- 認證授權后回調函數 *
- 根據openid判斷是否用戶已經存在
- 如果是新用戶,注冊并綁定,然后跳轉到手機號驗證界面
- 如果是老用戶,跳轉到主頁 */ router.get('/callback', function(req, res) { console.log('----weixin callback -----') var code = req.query.code;
var User = req.model.UserModel;
client.getAccessToken(code, function (err, result) { console.dir(err) console.dir(result) var accessToken = result.data.access_token; var openid = result.data.openid;
console.log('token=' + accessToken); console.log('openid=' + openid);
User.find_by_openid(openid, function(err, user){ console.log('微信回調后,User.find_by_openid(openid) 返回的user = ' + user) if(err || user == null){
console.log('user is not exist.') client.getUser(openid, function (err, result) { console.log('use weixin api get user: '+ err) console.log(result) var oauth_user = result; var _user = new User(oauth_user); _user.username = oauth_user.nickname; _user.nickname = oauth_user.nickname; _user.save(function(err, user) { if (err) { console.log('User save error ....' + err); } else { console.log('User save sucess ....' + err); req.session.current_user = void 0; res.redirect('/user/' + user._id + '/verify'); } }); });
}else{
console.log('根據openid查詢,用戶已經存在') // if phone_number exist,go home page if(user.is_valid == true){ req.session.current_user = user; res.redirect('/mobile') }else{ //if phone_number exist,go to user detail page to fill it req.session.current_user = void 0; res.redirect('/users/' + user._id + '/verify'); }
} }); }); });</pre>
上面的簡單介紹一下
wx_jsapi_sign(nodejs)
wx_jsapi_sign = wechat(微信) js-api signature implement.
- 支持集群,將獲得的前面寫到cache.json里
- 使用cache.json保存,比如用redis省事,更省內存
- 足夠小巧,便于集成
Install
npm install --save wx_jsapi_sign
Usage
copy config file
cp node_modules/wx_jsapi_sign/config.example.js config.js
change appId && appSecret
then mount a route in app.js
var signature = require('wx_jsapi_sign'); var config = require('./config')();
....
app.post('/getsignature', function(req, res){
var url = req.body.url;
console.log(url);
signature.getSignature(config)(url, function(error, result) {
if (error) {
res.json({
'error': error
});
} else {
res.json(result);
}
});
});</pre>
more usages seetest/public/test.html
Test
微信訪問網址http://yourserver.com:1342/test
原作者博客
我為什么要重寫這個模塊?
微信簽名7200秒可以查看一次,所以就要考慮緩存問題
- wx_jsapi_sign是一個開源項目,使用redis作為緩存,思路挺好,但依賴redis,還是有點重,沒必要
- xinshangshangxin寫的模塊使用cache.json做緩存,然后把獲取的時間保存到配置文件里,每次請求只要讀取文件即可。這個思路非常好,依賴少,省內存,簡單,支持集群 </ul>
- 他不太了解如何寫通用模塊(復用程度比較低)
- 代碼比較亂(抽取了配置,很好,但想art-template之類的都混在里面看的人頓時頭大)
- 沒有發布到npm上 </ul>
- 依賴管理(區分模塊依賴的,還是開發階段依賴的)
- npmjs.org上如何發布模塊 </ul>
- 敏感信息不能提交上去
- 部署服務器的時候,不會沖突(比如配置文件里有一個is_debug選項,服務器上必須是false,而開發階段是要用true的) </ul>
- 第一件事兒是思考,而不是想找一個隨便xx
- 不要造重復的輪子,除非必要(先到github或相關網站上找對應模塊,要有可以修改對應模塊源碼的能力)
- 反身而誠,樂莫大焉 </ul>
那哥們寫的已經很不錯了,但是有幾個問題
如果各位想了解是如何做的,請移步http://www.github.com/i5ting/wx_jsapi_sign
配置文件實際
上面的微信的菜單,db連接,還是wx_jsapi_sign都是基于配置的,使用配置文件會有一些問題
比如config.json作為配置文件,你需要在版本控制里放一個config.example.json,然后把config.json放到.gitinore里。
然后每個使用的人,需要先拷貝一個config.example.json為config.json。
這樣做的好處
另外配置文件格式,推薦json和yaml,而不是js,不要在配置文件了寫邏輯,雖然沒問題,但實為陋習。
糾正一下價值觀
很多人都認為現在啥模塊都有了,隨便找一個用就可以了,但這種想法是危險的
全文完
歡迎關注我的公眾號【node全棧】來自:http://my.oschina.net/nodeonly/blog/476894