【问题标题】:403 Forbidden when using csrf angularjs403 使用 csrf angularjs 时禁止
【发布时间】:2017-12-28 13:39:51
【问题描述】:

我在我的项目中使用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 (/getAccessTokenLINE) 发送请求时发生 403 Forbidden 错误,所以我认为这个文件并不重要)

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();
});

【问题讨论】:

  • 你是在哪里声明line.getAccessToken server.js
  • @Burdy 抱歉,我编辑了

标签: angularjs express csrf


【解决方案1】:

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

【讨论】:

  • 我检查了我的请求标头中的 cookie:Cookie:_csrf=emRIOclyiO6SH73Ur7yZhojT。而且我确信我可以得到这个值,因为我已经通过 console.log($cookies._csrf); 进行了测试
  • app.use(csrfProtection, function(req, res) { res.cookie('XSRF-TOKEN', req.csrfToken()); });你忘了下一个()
  • 没什么不同
  • 添加 next() 后,重新检查你的 $cookie 角度。
【解决方案2】:

如果你使用 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。跨域请求不会设置header。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-11-06
    • 2018-11-05
    • 2018-01-14
    • 2020-05-04
    • 2014-11-15
    • 2013-05-25
    • 1970-01-01
    • 2017-06-26
    相关资源
    最近更新 更多