Invalid Csrf token when making a cross origin request

Viewed 307

I have been stuck on it for a while now. I cant understand what is the cause for it. Basically i am making a fetch request to my node js rest api(/csrf-token) to get the csrf token cookie and i am successful in doing so. But when i make a post request from the client it gives me invalid csrf token but that's the part i don't understand because when i open up my devtools i can clearly see an x-xsrf-token header along with _csrf cookie in the request. I would really appreciate if someone can help me point out where iam going wrong. I am using csurf library and below is my code:

Backend :

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"
    })
});

My frontend code :

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 Answers
Related