1.connect中間件csrf前端
原理:在express框架中csrf 是經過connect 模塊的中間件來解決的。其原理是在前端構造一個隱藏的表單域「_csrf」 ,後端生成一個值,做爲該表單域,而後在提交表單的時候,將這個值提交到後端,後端再根據這個值來比較,若是和以前的值相等的,就認爲是正確的,不然就是錯誤的。 咱們來看看代碼:git
module.exports = function csrf(options) { options = options || {}; var value = options.value || defaultValue; return function(req, res, next){ // already have one var secret = req.session._csrfSecret; if (secret) return createToken(secret); // generate secret uid(24, function(err, secret){ if (err) return next(err); req.session._csrfSecret = secret; createToken(secret); }); // generate the token function createToken(secret) { var token; // lazy-load token req.csrfToken = function csrfToken() { return token || (token = saltedToken(secret)); }; // compatibility with old middleware Object.defineProperty(req.session, '_csrf', { configurable: true, get: function() { console.warn('req.session._csrf is deprecated, use req.csrfToken() instead'); return req.csrfToken(); } }); // ignore these methods if ('GET' == req.method || 'HEAD' == req.method || 'OPTIONS' == req.method) return next(); // determine user-submitted value var val = value(req); // check if (!checkToken(val, secret)) return next(utils.error(403)); next(); } } };
咱們看到,直接以function(req,res,next){} 返回,在這個函數裏面有一個 createToken 函數,就是生成token 的,將token的值直接綁定在請求對象req的屬性上,req.csrfToken = functiongithub
咱們能夠直接調用這個函數,生成值,返回給頁面,賦值給表單域。而後表單提交 通過checkToken 函數,比較是否相同,若是是就調用next 函數,不然直接調用utils.error(403) 了。express
2. cookie_secret 後端
express 能夠經過connect的中間件模塊cookieParser 來解決cookie
使用方法:session
connect() * .use(connect.cookieParser('optional secret string')) * .use(function(req, res, next){ * res.end(JSON.stringify(req.cookies)); * })
3.paypal 的lusca 模塊app
這個模塊很簡潔,能夠解決csrf,p3p,xframe,csp 等問題。使用起來很簡單。官方地址框架
原理: csrf 是直接調用express 框架的csrf來解決的,p3p和xframe ,csp 都是設置response header 來解決的。函數
調用方式爲:
var express = require('express'), appsec = require('lusca'), server = express(); server.use(appsec.csrf()); server.use(appsec.csp({ /* ... */})); server.use(appsec.xframe('SAMEORIGIN')); server.use(appsec.p3p('ABCDEF'));
也能夠直接這麼使用
server.use(appsec({ csrf: true, csp: { /* ... */}, xframe: 'SAMEORIGIN', p3p: 'ABCDEF' }));