一、關於cookie加密
cookie加密是讓客戶端用戶無法的值cookie明文信息,是數據安全的重要部分;一般的我們可以在保存cookie時對cookie信息進行加密,或者在res.cookie中對option對象的signed屬性設置設置成true即可。
二、使用 signed 屬性進行cookie加密
如下列代碼:
const express = require("express");
const cookieParser = require("cookie-parser");
var app = express();
app.use(cookieParser('secret'));
app.get("/",function(req,res){
res.send("主頁");
});
//獲取cookie
app.use(function(req,res,next){
console.log(req.signedCookies.name);
next();
});
//設置cookie
app.use(function(req,res,next){
console.log(res.cookie("name","zhangsan",{httpOnly: true,maxAge: 200000,signed: true}));
res.end("cookie為:"+req.signedCookies.name);
});
app.listen(8080);
簽名原理
Express用於對cookie簽名,而cookie-parser則是實現對簽名的解析。實質是把cookie設置的值和cookieParser('secret');中的secret進行hmac加密,之后和cookie值加“.”的方式拼接起來。
當option中signed設置為true后,底層會將cookie的值與“secret”進行hmac加密;
if(opts.signed){
sign(cookieVal, secret);
}
function sign (cookieVal, secret) {
return cookieVal + '.' + hmac(cookieVal, secret);
}
如何解析
cookie-parser中間件在解析簽名cookie時做了兩件事:
1.將簽名cookie對應的原始值提取出來
2.驗證簽名cookie是否合法
如下面代碼:
//將簽名后的cooki和密匙secret密匙傳入
function signedCookie (str, secret) {
if (typeof str !== 'string') {
return undefined
}
//驗證cookie以“s:”開頭
if (str.substr(0, 2) !== 's:') {
return str
}
//驗證簽名的值是否合法,返回true或false
var secrets = !secret || Array.isArray(secret) ? (secret || []) : [secret]
for (var i = 0; i < secrets.length; i++) {
var val = signature.unsign(str.slice(2), secrets[i])
if (val !== false) {
return val
}
}
return false
}
上面引入自signature模塊的unsign方法,他則是重新將得到的原始值進行相同簽名,然后再和之前的簽名值進行比較,結果相同則判斷簽名是否合法。 signature.unsign 代碼如下:
exports.unsign = function(val, secret){
if ('string' != typeof val) throw new TypeError("Signed cookie string must be provided.");
if ('string' != typeof secret) throw new TypeError("Secret string must be provided.");
var str = val.slice(0, val.lastIndexOf('.'))
, mac = exports.sign(str, secret);
return sha1(mac) == sha1(val) ? str : false;
};
三、直接對cookie值加密
node為我們提供了一個核心安全模塊“crypto”,它提供了很多安全相關的功能,如摘要運算、加密、電子簽名等。
這是,我們便可很輕易的封裝一個加密模塊:
const crypto=require('crypto');
module.exports={
//MD5封裝
MD5_SUFFIX:'s5w84&&d4d473885s2025s5*4s2',
md5:function(str){
var obj=crypto.createHash('md5');
obj.update(str);
return obj.digest('hex');
}
}
之后只需要進行相應導入即可:
const common=require('./MD5');
var str='123456';
var str=common.md5(str+'s5w84&&d4d473885s2025s5*4s2');
console.log(str);
設置cookie代碼如下:
const express=require("express");
const cookieParser=require("cookie-parser");
var cry = require('./md5');
var app=express();
var str='hello-123';
var str=cry.md5(str+'s5w84&&d4d473885s2025s5*4s2');
//設置中間件
app.use(cookieParser());
//獲取加密cookie
app.use(function(req,res,next){
console.log(req.cookies.userName);
next();
});
//設置並加密cookie
app.use(function(req,res,next){
res.cookie("userName", str, {maxAge: 5*60*1000, httpOnly: true});
res.end("set ok");
});
app.listen(8080);
如果是在判斷登錄時,只需將用戶輸入的賬號進行同樣加密操作在進行比較即可知道賬戶是否正確。
crypto所涉及的加密方式有很多,推薦大家都寫模塊引用,這樣更方便后期的維護。
