抱歉,我不太明白 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 ?对整个应用程序只使用一个还不够吗?
最佳答案
好像你在这里问了很多事情。
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 匹配来完成此操作。
您似乎缺少的是您必须:
secret
客户端的 cookie 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/