最终我成功发送了好的令牌值。以下是完整的答案。
AngularJS 在使用$http
服务进行请求时,会使用CSRF防护(Angular称其为XSRF)。
当执行XHR请求时,$http服务从一个cookie中读取一个令牌(默认为XSRF-TOKEN),并将其设置为HTTP头部(X-XSRF-TOKEN)。由于只有在您的域上运行的JavaScript才能读取该cookie,因此您的服务器可以确保XHR来自在您的域上运行的JavaScript。该头部不会被设置为跨域请求。
有许多文章解释了如何使用ExpressJS 3.xx发送XSRF-TOKEN,但一些事情在4.xx版本中发生了变化。Connect中间件不再包含在内。Express使用自己的中间件:cookie-parser、body-parser、express-session和csurf。
1 - 发送XSRF-TOKEN cookie
第一步是从后端向前端发送cookie(从Express到Angular):
var express = require('express');
var app = express();
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var session = require('express-session');
var config = require('./lib/config');
var csrf = require('csurf');
app.use(cookieParser(config.cookieSecret, { httpOnly: true }));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(session({
name: 'sessionID',
secret: config.sessionSecret,
cookie: {
path: '/',
httpOnly: true,
secure: false,
maxAge: 3600000
},
rolling: true,
resave: false,
saveUninitialized: true
}));
app.use(csrf());
app.use(function(req, res, next) {
res.cookie('XSRF-TOKEN', req.csrfToken());
next();
});
现在Angular能够在$http请求期间设置其HTTP头(X-XSRF-TOKEN)。 示例:
现在Angular可以在$http请求期间设置其HTTP头(X-XSRF-TOKEN)。示例:
<body ng-app="testApp">
<div ng-controller="LoginCtrl">
<form role="form" ng-submit="login()" >
<input type="email" ng-model="user.email" />
<input type="password" ng-model="user.password" />
<input type="submit" value="Log In" />
</form>
<p style="color:red">{{loginMsg}}</p>
</div>
</body>
<script>
var app = angular.module('testApp', ['ngResource']);
app.controller('LoginCtrl', function ($scope, $http) {
$scope.user = {};
$scope.loginMsg = '';
$scope.login = function () {
$http.post('/login', $scope.user).success(function () {
$window.location.href='/profile';
}).error(function () {
$scope.loginMsg = 'Wrong credentials, try again.';
});
};
});
</script>
2- 在非Angular表单中添加_csrf输入
这是我的问题,我不知道如何添加此输入。最终,我创建了一个名为$csrf
的新Angular服务:
app.factory('$csrf', function () {
var cookies = document.cookie.split('; ');
for (var i=0; i<cookies.length; i++) {
var cookie = cookies[i].split('=');
if(cookie[0].indexOf('XSRF-TOKEN') > -1) {
return cookie[1];
}
}
return 'none';
});
我在Plunker上创建了一个示例:http://plnkr.co/edit/G8oD0dDJQmjWaa6D0x3u
希望我的回答能够帮助到你。