Express csurf (csrf middleware), не работающий с XSRF в angularjs

Express и Angular имеют свое собственное промежуточное ПО csrf. Я не могу заставить их работать вообще, и в этом нет похожего последовательного руководства в Интернете. Я понимаю, что express 4.0 использует csurf в качестве своего промежуточного программного обеспечения csrf, и мне нужно установить X-XSRF-TOKEN на angularjs.

Разбросаны фрагменты о том, как это сделать, с информацией, которая иногда конфликтует:

Как проверить конечные точки, защищенные csrf в node.js/express

angular, django и csrf

CSURF Angular Внедрение

Но я попробовал их, и они не работают. Мой _csrf всегда undefined на Angular clientside, а csurf всегда дает success, несмотря на то, что токен csrf не был предоставлен клиенту.

Кроме того, я использую express-jwt для сохранения сеанса пользователя, поэтому я не уверен, что это будет мешать cookie-session (требуется curf).

Вот мое простое приложение angular/express для обработки регистра 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');
 });
 }
 }
]);

выразить 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 !== '*************') 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 is undefined. На стороне expressjs app.post('/login') выполняется полностью без провала, даже если токен csrf должен быть плохим (undefined, так как csrf на стороне Angular не работает). Это указывает на то, что csurf вообще не работает на экспресс-стороне.

Может ли кто-нибудь предоставить подробное объяснение для интеграции csurf в express 4.0, xsrf в Angular и заставить их работать вместе?

1 ответ

У меня были проблемы с интеграцией обоих, и они достигли следующей структуры (только соответствующие части):

выразить app.js

var cookieParser = require('cookie-parser');
var session = require('cookie-session');
var csrf = require('csurf');
app.use(session({
 secret: 'keyboard cat'
}));
app.use(cookieParser('secret'));
app.use(csrf());
app.use(function (req, res, next) {
 res.cookie("XSRF-TOKEN",req.csrfToken());
 return next();
});

В стороне AngularJS нет необходимости в изменениях. Он автоматически идентифицирует XSRF-TOKEN.

Теперь, чтобы объяснить фрагмент кода выше, мне нужно обратиться к lib csurf. Это промежуточное программное обеспечение для обработки всей аутентификации csrf, но оно реализует другую библиотеку csrf, называемую csrf. Этот csrf возвращает "класс" с четырьмя функциями (secret, secretSync, create, verify).

Что такое csurf, когда вы вызываете его промежуточное программное обеспечение, генерирует секрет через метод secretSync и сохраняет в вашем сеансе. Вы можете получить доступ к этому через переменную req.session.csrfSecret. Однако он не выполняет метод req.csrfToken, который использует этот секрет для возврата токена csrf. Чтобы правильно вернуть токен csrf, вам нужно вызвать его в другом промежуточном программном обеспечении.

Еще одна важная вещь: имя возвращаемого файла cookie должно быть "XSRF-TOKEN", а не "_csrf". Поэтому Angular автоматически идентифицирует его и добавляет в HTTP-запрос "X-XSRF-TOKEN", который идентифицируется промежуточным программным обеспечением csurf.

Надеюсь, это поможет.

licensed under cc by-sa 3.0 with attribution.