【发布时间】:2022-02-16 22:09:52
【问题描述】:
场景:
- 我的应用中有一个页面,用户似乎在会话/CSFR 过期后仍保持打开状态并返回
- 当他们尝试从该页面提交数据并且会话被拒绝时,我有一个功能可以打开登录模式
- 提交时,首先会向服务器发出一个请求以发出新的 CSRF 令牌
- 收到该令牌后,它会使用该新令牌,并将其与用户凭据一起发送以生成新会话
- 然后他们可以继续他们之前的工作
问题是在第 4 步,由于 CSRF 令牌无效,请求失败。
在服务器端,两条路由如下所示(使用 express、csurf):
const csrf = require("csurf");
const csrfProtection = csrf({ cookie: true });
const passport = require("passport");
//Issue new ajax csrf login token
app.get("/ajaxLoginToken", csrfProtection, function (req, res) {
const csrfToken = req.csrfToken();
res.json({ csrfToken });
console.log("New csrf token issued", csrfToken);
});
//AJAX login
app.post("/ajaxLogin", csrfProtection, function (req, res, next) {
passport.authenticate("local", async function (err, user, info) {
//This point is never reached due to csrf mismatch
在浏览器上,步骤 3 如下所示:
async requestNewToken() {
let response = await fetch("/ajaxLoginToken", {
method: "GET",
});
let responseBody = await response.json();
//Update csrf token
document.querySelector('meta[name="csrf-token"]').setAttribute("content", responseBody.csrfToken);
document.cookie = `_csrf=${responseBody.csrfToken}`;
然后发送步骤4,它在发送之前将csrf令牌添加到请求中
async login({email, password}) {
let response = await fetch(request.url, {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
"X-CSRF-Token": document.querySelector('meta[name="csrf-token"]').getAttribute("content")
},
body: JSON.stringify({email, password}),
//this always fails due to csrf token
当我尝试调试时,在登录请求中收到了新令牌,但它被拒绝了。任何帮助都会很棒 - 我已经为此苦恼了好几天。
【问题讨论】:
标签: node.js ajax express csrf csrf-token