发出跨源请求时无效的 Csrf 令牌

时间:2021-03-10 08:00:21

标签: node.js reactjs cross-domain csrf

我已经坚持了一段时间了。我无法理解它的原因是什么。基本上,我正在向我的节点 js rest api(/csrf-token) 发出一个获取请求以获取 csrf 令牌 cookie,并且我成功地这样做了。但是当我从客户端发出发布请求时,它给了我 无效的 csrf 令牌 但这就是我不明白的部分,因为当我打开我的开发工具时,我可以清楚地看到一个 x-xsrf-token 标头以及请求中的 _csrf cookie。如果有人能帮我指出我哪里出错了,我将不胜感激。我正在使用 csurf 库,下面是我的代码:

后端:

const corsOptions = {
origin: function (origin, callback) {
    if (whitelist.includes(origin)) {
        console.log("Origin", origin)
        callback(null, true)
    } else {
        callback(new HTTP401Error('Not allowed by CORS'))
    }
},
credentials: true,
methods: 'GET,POST,PUT, DELETE, OPTIONS',
allowedHeaders: "Origin, Content-type, Accept, Authorization, x-xsrf-token"
}

app.use(bodyparser.json())
app.use(bodyparser.urlencoded({ extended: true }))
const csrfprotection = csrf({
    cookie: true
})


app.use(cors(corsOptions))
app.use(helmet());
app.use(fileupload({
    createParentPath: true,
    limits: {
        fileSize: 1 * 1024 * 1024 * 1024 //2MB max file(s) size
    },
    abortOnLimit: true,
}))

const sessionMiddleware = session({
    name: process.env.SESS_NAME,
    secret: process.env.SESS_SECRET,
    resave: false,
    rolling: true,
    saveUninitialized: false,
    store: store,
    cookie: {
        httpOnly: true,
        sameSite: 'none',
        domain: process.env.NODE_ENV === 'production' ? '.domain.com' : {},
        secure: process.env.NODE_ENV === 'production' ? true : false,
        maxAge: parseInt(process.env.SESS_LIFETIME)
    }
})
app.set('trust proxy', 1);
app.use(sessionMiddleware)
app.use(csrfprotection)

app.get('/csrf-token', (req, res) => { // -->MY GET REQUEST WHICH SEND THE CSRF COOKIES
    // res.header('Cache-Control', 'private, no-cache, no-store, must-revalidate');
    res.cookie('XSRF-TOKEN', req.csrfToken())
    return res.status(200).json({
        message: "success"
    })
});

我的前端代码:

const handleLogin = async () => {
        const { csrftoken } = useSelector(state => state.csrfReducer)
        try {
            console.log("csrf token", csrftoken)
            const result = await fetch('https://api.domain.com/auth/login', {
                method: "POST",
                body: JSON.stringify({
                    email: values.email,
                    password: values.password
                }),
                headers: {
                    'Accept': 'application/json',
                    'Content-Type': 'application/json',
                    'X-XSRF-TOKEN': csrftoken
                },
                credentials: "include",
            })
            if (result.ok) {
                const data = await result.json()
                console.log(data)
            } else {
                throw result
            }
        } catch (err) {
            console.log(err)
        }
    }

0 个答案:

没有答案