@Stephan_Du_Toit yeah, sure. When it comes to the implementation, then I have done everything as described in the tutorial. The only difference is that I went with cookieSetter
and cookieGetter
as part of Strapi’s middleware because I think it’s the most elegant solution.
The most crucial thing is to set origin URLs correctly. You have to declare the full path (e.g. “https://my-strapi.com” and “https://my-frontend.com”) to your backend and your frontend.
This is my middleware.js
file:
module.exports = ({ env }) => ({
load: {
before: [
"cookieGetter",
"responseTime",
"logger",
"cors",
"responses",
"gzip",
],
order: [
"Define the middlewares' load order by putting their name in this array is the right order",
],
after: ["parser", "router", "cookieSetter"],
},
settings: {
cors: {
origin: [
env("CLIENT_URL", "http://localhost:8080"),
env("API_URL", "http://localhost:1337"),
],
},
cookieGetter: {
enabled: true,
},
cookieSetter: {
enabled: true,
},
},
});
Implementation details of both cookie functions are below. IMPORTANT: inside cookie setter you need to declare a domain
property (process.env.CLIENT_HOSTNAME
), which value is the hostname of your frontend, e.g. “my-frontend.com”.
// cookieSetter
module.exports = (strapi) => {
return {
initialize() {
strapi.app.use(async (ctx, next) => {
await next();
if (
ctx.request.url.startsWith("/auth/") &&
ctx.response.status === 200
) {
const { jwt: jwtToken } = ctx.response.body;
ctx.cookies.set("token", jwtToken, {
httpOnly: true,
secure: process.env.NODE_ENV === "production",
maxAge: 1000 * 60 * 60 * 24 * 14, // 14 Day Age
domain: process.env.CLIENT_HOSTNAME,
sameSite: process.env.NODE_ENV === "development" ? true : "none",
overwrite: true,
});
}
});
},
};
};
// cookieGetter
module.exports = (strapi) => {
return {
initialize() {
strapi.app.use(async (ctx, next) => {
if (
ctx.request &&
ctx.request.header &&
!ctx.request.header.authorization
) {
const token = ctx.cookies.get("token");
if (token) {
ctx.request.header.authorization = `Bearer ${token}`;
}
}
await next();
});
},
};
};
With this code I have a fully functional authorization process, which works like a charm.