在快递中提交表单时,CSRF令牌不起作用 [英] CSRF token not working when submitting form in express

查看:1116
本文介绍了在快递中提交表单时,CSRF令牌不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在我的快速应用程序中获取表单。我有一个中间件功能,将csrf令牌req.session._csrf传递给res.locals.csrf_token,因此该视图可以使用它。现在我试图在我的视图中使用本地变量,我从我的会话中间件得到一个禁止的错误。

i'm trying to get forms working in my express app. i have a middleware function that passes the csrf token, req.session._csrf, to res.locals.csrf_token, so the view can use it. now i'm trying to use the local variable in my view and i'm getting a forbidden error from my session middleware.

这是我的表单代码 - 我使用句柄作为我的模板引擎:

here's my form code - i'm using handlebars as my templating engine:

  <form method='post' action='/api/entries' enctype='multipart/form-data' >
    <input type='hidden' name='_csrf' value={{csrf_token}} />
    <input class='foo' type='text' />
    <input class='bar' type='text' />
    <button id='submit' type='submit'> SUBMIT
  </form>

我尝试引用csrf_token变量,带和不带双大括号,并且都不起作用。任何关于我做错什么的想法?错误:禁止发生在我的路由功能之前发送至/ api / entries甚至被调用。所以我很确定的问题是,我做错了引用csrf标记。

i've tried referencing the csrf_token variable with and without the double curly braces and neither works. any ideas on what i am doing wrong? the Error: Forbidden happens before my route function for POSTing to /api/entries is even called. so i'm pretty sure the problem is that i'm doing something wrong with referencing the csrf token..

* 编辑: *关于req.session._csrf已被弃用,请使用req.csrfToken()而不是登录到控制台,我做了:

*edit:*in regards to the "req.session._csrf is deprecated, use req.csrfToken() instead" getting logged to the console, i did:

grep -r '_csrf' .

在我的应用程序目录。这里是输出..它看起来不像我在任何地方引用它,除了视图,我隐藏的CSRF字段被命名为_csrf..

in my app directory. here was the output.. it doesn't look like i'm referencing it anywhere besides the view, where my hidden CSRF field is named "_csrf"..

./node_modules/express/node_modules/connect/lib/middleware/csrf.js:    var secret = req.session._csrfSecret;
./node_modules/express/node_modules/connect/lib/middleware/csrf.js:      req.session._csrfSecret = secret;
./node_modules/express/node_modules/connect/lib/middleware/csrf.js:      Object.defineProperty(req.session, '_csrf', {
./node_modules/express/node_modules/connect/lib/middleware/csrf.js:          console.warn('req.session._csrf is deprecated, use req.csrfToken() instead');
./node_modules/express/node_modules/connect/lib/middleware/csrf.js:  return (req.body && req.body._csrf)
./node_modules/express/node_modules/connect/lib/middleware/csrf.js:    || (req.query && req.query._csrf)
./v/home.hbs:    <input type='hidden' name='_csrf' value={{csrf_token}} />
./v/show.hbs:  <input type='hidden'  name='_csrf' value={{csrf_token}} />

这是我尝试POST到/ api / entries端点时遇到的整个错误堆栈(我愚蠢地忽略了之前提到这一点,但是我正在使用connect-redis进行会话中间件):

here is the entire error stack i'm getting when trying to POST to the /api/entries endpoint (i stupidly neglected to mention this before, but i'm using connect-redis for session middleware):

Error: Forbidden
    at Object.exports.error (appFolder/node_modules/express/node_modules/connect/lib/utils.js:63:13)
    at createToken (appFolder/node_modules/express/node_modules/connect/lib/middleware/csrf.js:82:55)
    at Object.handle (appFolder/node_modules/express/node_modules/connect/lib/middleware/csrf.js:48:24)
    at next (appFolder/node_modules/express/node_modules/connect/lib/proto.js:193:15)
    at next (appFolder/node_modules/express/node_modules/connect/lib/middleware/session.js:318:9)
    at appFolder/node_modules/express/node_modules/connect/lib/middleware/session.js:342:9
    at appFolder/node_modules/connect-redis/lib/connect-redis.js:101:14
    at try_callback (appFolder/node_modules/redis/index.js:580:9)
    at RedisClient.return_reply (appFolder/node_modules/redis/index.js:670:13)
    at ReplyParser.<anonymous> (appFolder/node_modules/redis/index.js:312:14)

编辑2: connect-redis.js中的错误是试图通过会话ID获取当前会话并失败的功能。不知道为什么会发生这种情况,我的connect-redis设置看起来是正确的。这是杀了我

edit 2: the error in connect-redis.js is a function trying to get the current session by the session ID and failing. don't know why this would be happening, my connect-redis setup looks correct. this is killing me

推荐答案

CSRF语法在最新版本的Express / Connect中略有变化。你现在想要你的中间件看起来像这样:

CSRF syntax has changed slightly in the latest versions of Express/Connect. You now want your middleware to look like this:

.use(express.csrf())
.use(function (req, res, next) {
  res.cookie('XSRF-TOKEN', req.csrfToken());
  res.locals.csrftoken = req.csrfToken();
  next();
})

要测试代码,请注意,您首先需要获取表单页面以生成CSRF令牌。只有这样,你的POST才能成功。如果失败,您需要在浏览器中重新加载页面,然后再次尝试POST。

For testing your code, note that you first need to GET the form page in order to generate the CSRF token. Only then will your POST succeed. If it fails, you need to reload the page in the browser before trying to POST again.

这篇关于在快递中提交表单时,CSRF令牌不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆