使用AngularJS和Express的错误CSRF令牌
我想在我的应用程序中添加一个使用MEAN堆栈的CSRF保护.
我尝试过某人已经给出的答案:CSRF Protection in ExpressJS 但这是旧的快递版本,所以我做了一些改变: app.use(cookieParser(config.cookieSecret,{ httpOnly: true })); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false })); app.use(session({ secret: config.sessionSecret,resave: false,saveUninitialized: true })); app.use(passport.initialize()); app.use(passport.session()); app.use(flash()); app.use(csrf({value: function(req) { var token = (req.body && req.body._csrf) || (req.query && req.query._csrf) || (req.headers['x-csrf-token']) || (req.headers['x-xsrf-token']); return token; } })); app.use(function(req,res,next) { res.cookie('XSRF-TOKEN',req.csrfToken()); next(); }); 我可以在我的应用程序上看到名为XSRF-TOKEN的令牌(使用Chrome检查). 但是当我发布一个表单(Angular frontend)时,我有一个关于令牌的错误: {“message”:“csrf token”,“error”:{“expose”:true,“code”:“EBADCSRFTOKEN”,“statusCode”:403,“status”:403}} 我错过了什么 ?我想知道req.csrfToken()是否生成Angular给出的好令牌… 编辑: 我只看到AngularJS在$http请求中使用了XSRF-TOKEN.所以我想我必须在我的表单中添加一个隐藏的输入来发布csrf值,由Express检查,但是如何? 解决方法
最后我能够发送好的令牌值.这是完整的答案.
在使用$http服务发出请求期间,AngularJS使用CSRF保护(Angular称为XSRF).
有很多帖子解释了如何使用ExpressJS 3.xx发送XSRF-TOKEN,但有些东西随4.xx版本而变化. Connect中间件不再包括在内. Express使用自己的middelware:cookie-parser,body-parser,express-session和csurf. 1 – 发送XSRF-TOKEN cookie 第一步是将cookie从后端发送到前端(Express to 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'); //config.js file with hard-coded options. 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,saveUninitialized: true })); app.use(csrf()); app.use(function(req,next) { res.cookie('XSRF-TOKEN',req.csrfToken()); next(); }); 现在,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 希望我的回答会有所帮助. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |