403使用csrf angularjs时禁止使用

时间:2017-07-22 14:32:41

标签: angularjs express csrf

我在我的项目中使用csurf库,但它不起作用。这是我的代码:

server.js

var express      = require('express');
var bodyParser   = require('body-parser');
var cookieParser = require('cookie-parser');
var csrf         = require('csurf');
var line         = require('./server/line');

app.use(cookieParser());
var csrfProtection = csrf({ cookie: true})

app.use(csrfProtection, function(req, res) {
    res.cookie('XSRF-TOKEN', req.csrfToken());
});

app.use(function (err, req, res, next) {
    if (err.code !== 'EBADCSRFTOKEN') return next(err) 

    res.status(403)
    res.send('form tampered with')
})

app.post('/getAccessTokenLINE', line.getAccessToken);

auth.js(我在标题和正文中添加' _csrf')

angular.module('auth', ['openline', 'ngCookies'])
    .config(function ($stateProvider) {
        //my config
    })
    .factory('Auth', function ($http, $window, $rootScope, $cookies) {
        return {
            getAccessTokenLINE: function() {
                return $http.post($rootScope.server.url + '/getAccessTokenLINE', {
                    channelId     : $window.sessionStorage.lineChannelId,
                    channelSecret : $window.sessionStorage.lineChannelSecret,
                    callbackURL   : $window.sessionStorage.callbackURL,
                    getTokenURL   : $window.sessionStorage.lineGetTokenURL,
                    code          : $window.sessionStorage.authorizationCode,
                    _csrf         : $cookies._csrf
                },
                {
                    headers: {
                        _csrf         : $cookies._csrf
                    }
                });
        }
}

line.js(我向API发送请求时发生403 Forbidden错误(/ getAccessTokenLINE),所以我觉得这个文件并不重要)

var request = require('request');

function getAccessToken(req, res, next) {
    var channelId         = req.body.channelId;
    var channelSecret     = req.body.channelSecret;
    var callbackURL       = req.body.callbackURL;
    var getTokenURL       = req.body.getTokenURL;
    var authorizationCode = req.body.code;

    request.post({
        uri: getTokenURL,
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
        },
        form: {
            grant_type    : 'authorization_code',
            client_id     : channelId,
            client_secret : channelSecret,
            redirect_uri  : callbackURL,
            code          : authorizationCode
        }
    }, function(error, response, body) {
        if (!error && response.statusCode == 200) {
            return res.send(body);
        } else {
            return res.send(response.statusCode, error);
        }
    });
}

我试图改变

var csrfProtection = csrf({ cookie: true})

var csrfProtection = csrf({ cookie: true, ignoreMethods: ['GET', 'POST', 'HEAD', 'OPTIONS']})

然后我可以正常访问我的API。所以,我认为设置没有错。

我不明白出了什么问题。

编辑:我找到了解决方案。

app.use(cookieParser());
app.use(csrf());
app.use(function(req, res, next) {
    res.cookie('XSRF-TOKEN', req.csrfToken());
    return next();
});

2 个答案:

答案 0 :(得分:0)

在Express代码中 res.cookie('XSRF-TOKEN', req.csrfToken()); 因此,您的csrf cookie将具有密钥' XSRF-TOKEN'。您无法从_csrf密钥获取Cookie _csrf: $cookies._csrf

答案 1 :(得分:0)

如果您使用angularjs,则只需在服务器端添加csrf代码即可。例如:

var bodyParser = require('body-parser')
var cookieParser = require('cookie-parser')
var csrf = require('csurf')
var express = require('express')

var app = express()
app.use(bodyParser.urlencoded({ extended: false }))
app.use(cookieParser())
app.use(csrf({ cookie: true }))

// error handler
app.use(function (err, req, res, next) {
  if (err.code !== 'EBADCSRFTOKEN') return next(err)

  // handle CSRF token errors here
  res.status(403)
  res.send('Error messages')
})

而angularjs将自行完成其余工作(reference - 转到安全注意事项部分)

  

跨站点请求伪造(XSRF)保护

     

XSRF是一种攻击技术,攻击者可以通过该技术欺骗经过身份验证的用户在网站上不知不觉地执行操作。 AngularJS提供了一种对抗XSRF的机制。执行XHR请求时,$ http服务从cookie(默认情况下为XSRF-TOKEN)读取令牌并将其设置为HTTP头(X-XSRF-TOKEN)。由于只有在您的域上运行的JavaScript才能读取Cookie,因此您的服务器可以确保XHR来自您域上运行的JavaScript。不会为跨域请求设置标头。