nodejs服務端實現微信小遊戲登入
阿新 • • 發佈:2018-12-12
nodejs服務端實現微信小遊戲登入的驗證與解密資訊
本文章主要借鑑於微信公眾平臺開放介面進行相應功能的開發,參照流程時序圖如:
目錄
文章目錄
小遊戲客戶端(結合cocos creator客戶端開發)
1.小程式呼叫wx.login() 獲取 臨時登入憑證code ,並回傳到開發者伺服器。
2.小程式呼叫wx.getUserInfo()獲取使用者的加密資訊,並傳給開發者伺服器,可通過解密演算法,開發者得到使用者資訊。
3.開發者伺服器以code換取 使用者唯一標識openid 和 會話金鑰session_key。之後開發者伺服器可以根據使用者標識來生成自定義登入態,用於後續業務邏輯中前後端互動時識別使用者身份。
Step1: wx.login(OBJECT)
呼叫介面wx.login() 獲取臨時登入憑證(code)
OBJECT引數
引數名 | 型別 | 說明 | 必填
-------- | —
timeout | Number |超時時間,單位 ms |否
success | Function|介面呼叫成功的回撥函式|否
fail |Function |介面呼叫失敗的回撥函式|否
complete |Function |介面呼叫結束的回撥函式(呼叫成功、失敗都會執行)|否
Success返回引數
引數名 | 型別 | 說明 |
---|---|---|
errMsg | String | 呼叫結果 |
code | String | 使用者登入憑證(有效期五分鐘)。開發者需要在開發者伺服器後臺呼叫 api,使用 code 換取 openid 和 session_key 等資訊 |
Step2: wx.getUserInfo(OBJECT)
客戶端呼叫介面wx.getUserInfo()獲取使用者資訊等(userInfo等)
OBJECT引數
引數名 | 型別 | 必填 | 說明 |
---|---|---|---|
withCredentials | Boolean | 否 | 是否帶上登入態資訊 |
lang | String | 否 | 指定返回使用者資訊的語言,zh_CN 簡體中文,zh_TW 繁體中文,en 英文。預設為en。 |
timeout | Number | 否 | 超時時間,單位 ms |
success | Function | 否 | 介面呼叫成功的回撥函式 |
fail | Function | 否 | 介面呼叫失敗的回撥函式 |
complete | Function | 否 | 介面呼叫結束的回撥函式(呼叫成功、失敗都會執行) |
Success返回引數
引數名 | 型別 | 說明 |
---|---|---|
userInfo | OBJECT | 使用者資訊物件,不包含 openid 等敏感資訊 |
rawData | String | 不包括敏感資訊的原始資料字串,用於計算簽名。 |
signature | String | 使用 sha1( rawData + sessionkey ) 得到字串,用於校驗使用者資訊,參考文件 signature。 |
encryptedData | String | 包括敏感資料在內的完整使用者資訊的加密資料,詳細見加密資料解密演算法 |
iv | String | 加密演算法的初始向量,詳細見加密資料解密演算法 |
客戶端相關程式碼
```JavaScript
//微信小遊戲微信登入方法
wechatGameLogin :function(){
var self = this;
wx.login({
success : function(code){
console.log("code is ",code);
code.appid = "應用appid";
code.secret = "應用金鑰";
if(code != null){
//發起微信請求
wx.request({
url : "開發者伺服器路由地址",
data : code,
header : {},
method : "POST",
dataType : "json",
success : function(res){
console.log("res is ",res);
//獲得session_key
self.sessionKey = res.data;
console.log(res.data);
wx.getUserInfo({
success : function(res){
console.log("res is ",res);
res.sessionKey = self.sessionKey.data;
//儲存使用者資訊
console.log("在微信登入裡面暱稱是 :"+res.userInfo.nickName);
cc.find("PebmanentNode").getComponent("UserInfo").nameUser = res.userInfo.nickName;
console.log("使用者名稱是:",cc.find("PebmanentNode").getComponent("UserInfo").nameUser);
//儲存使用者頭像資訊
cc.find("PebmanentNode").getComponent("UserInfo").pictureUser = res.userInfo.avatarUrl;
wx.request({
url : "開發者伺服器路由地址",//向伺服器傳送微信返回的使用者資訊,由服務端解密得到使用者資訊
data : res,
header : {
},
method : "POST",
dataType : "json",
success : function(result){
console.log("res is ",result);
cc.find("PebmanentNode").getComponent("GetServer").GetServerMsg(result.data);
},
fail :function(res){
console.log(res);
console.log("userInfo request fail");
},
complete :function(){
},
})
}
});
},
fail :function(){
console.log("fail");
},
complete :function(){
},
})
}
},
fail : function(){
},
complete : function(){
},
});
},
nodejs服務端
相關程式碼
function LoginCode(userInfo,res) {//接收客戶端傳送過來的資訊,其中包括code和appid
let body=userInfo.bindingMsg;
let code=body.code;
console.log("code:",code);
appid=body.appid;
let secret=body.secret;
request({//開發者伺服器以code換取 使用者唯一標識openid 和 會話金鑰session_key。
method: 'get',
url:"https://api.weixin.qq.com/sns/jscode2session?appid="+appid+"&secret="+secret+"&js_code="+code+"&grant_type=authorization_code"
}, function(err, res1, body){
//使用者伺服器返回的數值
console.log("微信返回的資訊:",res1.body);
let result={
result:"ok"
};
console.log("session_key:",JSON.parse(res1.body).session_key);
sessionkeyList.push(JSON.parse(res1.body).session_key);
result.result="ok";
result.msg="sessionKey";
result.data=JSON.parse(res1.body).session_key;//為了方便確認下次使用者請求是哪個session_key直接傳給客戶端,建議不要直接傳session_key
res.send(JSON.stringify(result));
});
}
function getUserInfo(userInfo,res){
let signature2 = sha1(body.rawData + sessionkeyList[i]);
if (body.signature != signature2) return res.json("資料簽名校驗失敗");
// 解密
let pc = new WXBizDataCrypt(appid, sessionkeyList[i]);
let data = pc.decryptData(body.encryptedData,body.iv);
console.log('解密後用戶資訊: ', data);
console.log('解密後用戶資訊型別: ', typeof data);
}
注:
詳細解密演算法例項請點選下載官方程式碼例項.
nodejs伺服器整個程式碼請點選 github專案連結