加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

使用AngularJS和Express的错误CSRF令牌

发布时间:2020-12-17 17:05:56 所属栏目:安全 来源:网络整理
导读:我想在我的应用程序中添加一个使用MEAN堆栈的CSRF保护. 我尝试过某人已经给出的答案:CSRF Protection in ExpressJS 但这是旧的快递版本,所以我做了一些改变: app.use(cookieParser(config.cookieSecret,{ httpOnly: true }));app.use(bodyParser.json());a
我想在我的应用程序中添加一个使用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).

When performing XHR requests,the $http service reads a token from a
cookie (by default,XSRF-TOKEN) and sets it as an HTTP header
(X-XSRF-TOKEN). Since only JavaScript that runs on your domain could
read the cookie,your server can be assured that the XHR came from
JavaScript running on your domain. The header will not be set for
cross-domain requests.

有很多帖子解释了如何使用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

希望我的回答会有所帮助.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读