為了應用的有效性,以及服務的安全性,特使用了應用驗簽,簽名使用了sha1加密。
簽名參數包含
AppId
AppSecret
timestamp 當前時間戳
signaturenonce 隨機字符串
提交時的簽名signature由以上參數排序后sha1加密而來的。
生成簽名的時候需要用到AppSecret,但是提交請求的時候不提交AppSecret
會在服務端獲取正確的AppSecret后生成簽名,進行對比驗簽
關鍵代碼如下
```
// 生成簽名
const getSign = function(data) {
// 這只是一個簡單的鑒權功能,適用于app和小程序,h5盡量不要使用,appsecret明文泄密(可以嘗試JS混淆加密),形同虛設。
// 客戶端:獲取簽名的流程 取得當前時間戳timestamp,隨機字符串SignatureNonce,配合上appid和appsecret組成一個對象,和傳過來的data參數合并,序列化后用sha1加密的到的就是signature簽名,注意appsecret不傳遞到服務器
// 服務端解密:信息通過header傳遞,服務器獲取后,根據傳遞的appid 查詢 appsecret,查詢不到直接出拋異常,再合上傳遞過去的所有參數,序列化sha1加密后和signature對比,如果一致則驗簽通過。
let Sign, timestamp = parseInt((new Date()).getTime() / 1000), SignatureNonce;
//生成SignatureNonce,可以在這里處理一下
SignatureNonce = sha1("lwwan_key_" + getrandomNum(5) + getrandomNum(6));
let str = {
appid: AppId,
timestamp: timestamp,
appsecret: config.MARK,
signaturenonce: SignatureNonce,
}
//合并參數
var objstr = jsonSort(getExtend(str,data));
Sign = {
appid: AppId,
signaturenonce: SignatureNonce,
timestamp: timestamp,
signature: sha1(objstr) //簽名
}
return Sign;
}
// 隨機數
const getrandomNum = function(num) {
let rnd = "";
for (let i = 0; i < num; i++)
rnd += Math.floor(Math.random() * 10);
return rnd;
}
// 合并對象
const getExtend = function(target, source) {
for (var obj in source) {
target[obj] = source[obj];
}
return target;
}
// 對象序列化
function jsonSort(jsonObj) {
let arr = [];
for (var key in jsonObj) {
arr.push(key)
}
arr.sort();
let str = '';
for (var i in arr) {
str += arr[i] + "=" + jsonObj[arr[i]] + "&"
}
return str.substr(0, str.length - 1)
}
```