koa - 为什么在 koa 上需要不止一个 key ?

标签 koa secret-key koa2

抱歉,我不太明白 key 在 koa 中是如何工作的。在 koa 中,有keys字段上 app将像这样使用的对象:

const app = new Koa();
app.keys = ['some secret', 'another secret', 'or more ...']; // it's an
                                                             // array right?

然后,当使用 koa-csrf中间件,默认内置 csrf.middleware不使用 app.keys 提供的 key .如果我使用
默认中间件,我需要创建另一个中间件来设置
session 中的 key 。
app.use(session()); // koa-generic-session
app.use(async (ctx, next) => {               // without this custom middleware
  ctx.session.secret = 'yet another secret'; // POST /protected-route
  await next();                              // will give 403
});                                          // missing secret
csrf(app);
app.use(csrf.middleware);

当我使用 Flask 时,我只需要提供一个 key
string 设置不是 array .为什么需要多个 key ?对整个应用程序只使用一个还不够吗?

最佳答案

好像你在这里问了很多事情。

  • 您可以供应Koa app.keys = [...]用于 key 轮换的多个 key 。

    例如,如果您想每个月生成一个新 key ,您可以使用它签署新 cookie,而不会立即使所有旧 cookie 失效。相反,您更愿意让旧 cookie 自然过期。

    如果您不关心 key 轮换,那么您只需使用 app.keys = ['mysecret']你永远不会改变。
  • koa-csrf的中间件实际上确实使用了您通过 app.keys= 设置的 key .

    Koa通行证app.keys进入其 Cookies 实例( https://github.com/pillarjs/cookies ),以便内置 this.cookies.get()this.cookies.set()将使用 key (如果提供)。
    koa-session使用 Koa 的内置 this.cookies.{get,set} .
    koa-csrf用途 koa-session .

  • 但这一切都无关紧要。

    403 响应并不是提示您没有设置 app.keys= secret 。它提示您没有提供 CSRF token (又名 secret ),更不用说有效的 token 了。

    您手动设置的“修复”this.session.secret只是手动设置 koa-csrf 查找 CSRF token 的值。您绕过了 CSRF 系统的整个安全措施。

    CSRF token 系统的全部意义在于确保某人击中 protected 端点实际上来自于,例如 <form>。从您控制的页面发布到该端点。

    它通过生成 token ,将其保存在 cookie 中,将 token 附加到表单,然后在提交时确保表单 token 与 session token 匹配来完成此操作。

    您似乎缺少的是您必须:
  • 生成CSRF token
  • 将其设置为 secret客户端的 cookie
  • 向客户端公开 CSRF token ,以便他们将其提交到 protected 端点。
  • 在 protected 端点上,确保客户端发送与其“ secret ”cookie 中的 CSRF token 匹配的 CSRF token 。 Here are the places
    koa-csrf 检查以找到该 token 。

  • koa-csrf this.csrf调用 #1 和 #2。你必须实现#3。 koa-csrf this.assertCSRF #4。

    所以,总的来说,这就是它的外观(未经测试):
    var koa = require('koa')
    var csrf = require('koa-csrf')
    var session = require('koa-session')
    var Router = require('koa-router');
    var bodyParser = require('koa-bodyparser');
    
    var app = koa()
    app.keys = ['session secret']
    app.use(session())
    app.use(bodyParser())
    csrf(app)
    app.use(csrf.middleware)
    
    var router = new Router();
    
    router.get('/messages', function*() {
      this.render('new_message_form.html', {
        token: this.csrf   // this call also sets `this.session.secret` for you
      });
    });
    
    router.post('/messages', function*() {
      this.assertCSRF(this.request.body);
    
      // If we get this far, then the CSRF check passed
      yield database.insertMessage(this.body.message);
    });
    
    app.use(router.routes());
    app.listen(3000, () => console.log('server listening on 3000'));
    

    这就是“new_message_form.html”的样子。请注意,我正在设置一个隐藏字段 _csrf这样当用户提交时,this.csrf生成的token被发送到我 protected 端点,并且 _csrf field 是 koa-csrf 检查以查找提交的 token 的地方之一。
    <form action="/messages" method="POST">
      <input type="hidden" name="_csrf" value="{{ token }}">
      <input type="message" name="message" placeholder="Write your message here...">
      <button type="submit">Save Message<button>
    </form>
    

    关于koa - 为什么在 koa 上需要不止一个 key ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35362507/

    相关文章:

    koa - 使用 koa 避免 `this`

    javascript - 如何在Koa项目中为Pug添加自定义模板功能?

    git - 当我推送到 GitHub 时如何处理 secret API key ,以便我的项目在克隆 repo 协议(protocol)时仍然有效?

    python - 我如何正确更改 Django Web 应用程序中分配的 key

    node.js - 如何使用 koajs 发送 http 响应

    javascript - Koa.js中的route()不是一个函数

    javascript - 我应该如何向 koa 后端发送 GET 请求以返回条件结果?

    node.js - Firebase函数: koa. js服务器如何部署

    iphone - 在 iPhone 源和项目资源上存储 key

    javascript - Koa-session 在附加对象后被重置?