See update below...
My React front-end is able to call upon my Node back-end API. However, when an external site calls upon my API, it receives an error (for POST requests but not for GET requests).
App setup includes:
const express = require("express");
const cookieParser = require("cookie-parser");
const csurf = require("csurf");
var cors = require("cors");
var corsOptions = {
origin: process.env.CORS_ORIGIN_URL.split(","),
credentials: true,
exposedHeaders: ["set-cookie"],
};
app.use(cors(corsOptions));
app.use(
cookieParser(process.env.COOKIE_SECRET, {
sameSite: true,
httpOnly: true,
secure: process.env.NODE_ENV === "production",
maxAge: process.env.COOKIE_MAX_AGE,
})
);
// If I comment out the next 5 lines, external services CAN call upon my API
app.use(csurf({ cookie: true }));
app.use(function (req, res, next) {
res.cookie("XSRF-TOKEN", req.csrfToken());
next();
});
app.use("/api/csrf", (req, res) => {
return res.status(200).json({
status: true,
csrfToken: req.csrfToken(),
});
});
app.use("/api", api);
If I comment out the CSRF part (the 5 lines) of the setup, then external services ARE able to call upon my API. How should I adjust this CSRF setup to make my application work also with "external" API calls?
Update
I've updated the CSRF configuration to the setup below. Would this be a secure setup? The idea is to use CSRF except for endpoints that need to be reachable to external services. res.cookie("XSRF-TOKEN", req.csrfToken()); no longer seems to work.
app.use(
cookieParser(process.env.COOKIE_SECRET, {
sameSite: true,
httpOnly: true,
secure: process.env.NODE_ENV === "production",
maxAge: process.env.COOKIE_MAX_AGE,
})
);
var csrf = csurf({ cookie: true });
app.use(function (req, res, next) {
if (req.url === '/api/mollie_webhook') {
return next();
} else {
app.use(csrf);
// I think this is not allowed, since we already have app.use 4 lines up, but don't know how else to do this...
// it correctly gets to this point
res.cookie("XSRF-TOKEN", req.csrfToken());
// but then not to this point
app.use("/api/csrf", (req, res) => {
return res.status(200).json({
status: true,
csrfToken: req.csrfToken(),
});
});
}
});
app.use("/api", api);
from How to exclude an endpoint from CSRF middleware
No comments:
Post a Comment