Express和Angular都有自己的csrf中间件 . 我根本无法让他们工作,互联网上似乎没有任何关于此问题的连贯指南 . 我的理解是express 4.0使用csurf作为其csrf中间件,我必须在angularjs上设置 X-XSRF-TOKEN
.
有关如何执行此操作的分散部分,有时会发生冲突的信息:
How to test endpoints protected by csrf in node.js/express
但我尝试过它们并且它们不起作用 . 我的 _csrf
在Angular客户端上总是 undefined
,尽管客户端没有给出csrf令牌,但csurf总是给出 success
.
此外,我使用 express-jwt
来保持用户会话,所以我不确定这是否会干扰 cookie-session
(curf所需) .
这是我用csrf处理注册的简单角度/快速应用程序(不工作):
angular app.js
var app = angular.module('app', ['ngCookies', 'ui.router']);
app.config(function($stateProvider) {
$stateProvider.state('register', {
url: '/register',
controller: 'RegisterCtrl',
templateUrl: 'views/register.html'
});
});
// register csrf
app.run(['$http', '$cookies', function($http, $cookies) {
$http.defaults.headers.post['X-XSRF-TOKEN'] = $cookies.csrftoken;
}]);
// controller
app.controller('RegisterCtrl', ['$scope', '$cookies', '$http',
function($scope, $cookies, $http) {
$scope.data = { email: "", password: "", _csrf: $cookies._csrf};
$scope.submitForm = function() {
// This will alert 'undefined'
alert("This is csrf token: " + $scope.data._csrf);
$http.post('/register', data).success(function(done) {
console.log('success');
var jwt_token = done["jwt_token"];
// save token to local storage.
}).error(function(err) {
console.log('error');
});
}
}
]);
express app.js
var express = require('express');
var app = express();
var http = require('http').Server(app);
var expressJwt = require("express-jwt");
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({extended: true});
app.use(bodyParser.json());
// csrf setup
var session = require('cookie-session');
var csrf = require('csurf');
app.use(session({
secret: 'keyboard cat'
}));
app.use(csrf());
// This part taken from csurf guide:
// https://github.com/expressjs/csurf
app.use(function(err, req, res, next) {
if (err.code !== 'EBADCSRFTOKEN') return next(err)
res.status(403);
res.send('session has expired or form tampered with');
});
app.post("/login", function(req, res) {
var email = req.body.email;
var password = req.body.password;
// save user to db ...
var jwt_token = // create and sign jwt token to be given back to registered user
res.json({"jwt_token": jwt_token});
});
http.listen(3000, function() {
console.log("Express started");
});
现在,如果我提交注册表, alert()
会说 _csrf
是 undefined
. 在expressjs方面, app.post('/login')
一直运行而没有失败,即使csrf令牌应该是坏的( undefined
,因为角度侧的csrf不起作用) . 这表明 csurf
在快车方面根本不起作用 .
有人可以提供 in-depth 解释来集成快递4.0中的 csurf
,Angular中的xsrf,让它们一起工作吗?
1 回答
我在整合两者时都遇到了问题,并达到了以下结构(只是相关部分):
express app.js
在AngularJS方面,不需要改变 . 它会自动识别XSRF-TOKEN .
现在,为了解释上面的代码,我需要引用 csurf lib . 它是一个处理所有csrf身份验证的中间件,但它实现了另一个名为 csrf 的csrf库 . 此csrf返回带有四个函数的"class"(secret,secretSync,create,verify) .
csurf所做的是,当你调用它的中间件时,通过secretSync方法生成一个秘密并存储在你的会话中 . 您可以通过变量req.session.csrfSecret访问它 . 但是,它不执行req.csrfToken方法,该方法使用此秘密返回csrf令牌 . 要正确返回csrf令牌,您需要在另一个中间件中调用它 .
另一个重要的事情,返回cookie的名称必须是“XSRF-TOKEN”,而不是“_csrf” . 因此,Angular会自动识别它并将HTTP请求附加到“X-XSRF-TOKEN”,这是由csurf中间件识别的 .
希望能帮助到你 .