System Information
- Strapi Version: 4.1**
- Operating System: Windows 11
- Database: Postgress
- Node Version:
- NPM Version:
- Yarn Version:
I wanted roles of users so I modified the response by adding extensions/strapi-server.js
// path: src/extensions/users-permissions/strapi-server.js
module.exports = (plugin) => {
const sanitizeOutput = (user) => {
const {
password,
resetPasswordToken,
confirmationToken,
...sanitizedUser
} = user; // be careful, you need to omit other private attributes yourself
return sanitizedUser;
};
plugin.controllers.user.me = async (ctx) => {
if (!ctx.state.user) {
return ctx.unauthorized();
}
const user = await strapi.entityService.findOne(
"plugin::users-permissions.user",
ctx.state.user.id,
{
populate: {
role: {
fields: ["type"],
},
},
}
);
ctx.body = sanitizeOutput(user);
};
return plugin;
};
So it looks like this, now to add cookie from Server Side i.e. HTTP Only, I added my custom endpoint (" /auth/login") in
src/api/custom
const axios = require("axios");
module.exports = {
// GET /auth/cookielogin
async index(ctx) {
// Capture the request body (identifier and password)
const { body } = ctx.request;
// Build Strapi's Absolute Server URL.
// Copied from https://github.com/strapi/strapi/blob/86e0cf0f55d58e714a67cf4daee2e59e39974dd9/packages/strapi-utils/lib/config.js#L62
const hostname = "localhost";
// const hostname =
// strapi.config.environment === "development" &&
// ["127.0.0.1", "0.0.0.0"].includes(strapi.config.server.host)
// ? "localhost"
// : strapi.config.server.host;
const absoluteURL = `http://${hostname}:${strapi.config.server.port}`;
const sanitizeOutput = (user) => {
const {
password,
resetPasswordToken,
confirmationToken,
...sanitizedUser
} = user; // be careful, you need to omit other private attributes yourself
return sanitizedUser;
};
try {
console.log("Tryin to login");
// Now submit the credentials to Strapi's default login endpoint
let { data } = await axios.post(`${absoluteURL}/api/auth/local`, body);
const populatedUser = await strapi.entityService.findOne(
"plugin::users-permissions.user",
data.user.id,
{
populate: {
role: {
fields: ["type"],
},
},
}
);
data.user = sanitizeOutput(populatedUser);
// Set the secure cookie
if (data && data.jwt) {
ctx.cookies.set("jwt", data.jwt, {
httpOnly: true,
secure: false,
maxAge: 1000 * 60 * 60 * 24 * 14, // 14 Day Age
domain: "localhost",
});
}
// Respond with the jwt + user data, but now this response also sets the JWT as a secure cookie
return ctx.send(data);
} catch (error) {
console.log("An error occurred:", error.response);
return ctx.badRequest(null, error);
}
}
};
Now from my Frontend, I am calling /auth/login, which returns just and user and sets the cookie from server i.e. HTTP Only, Now When I am calling /users/me, it says UnAuthorized
I know what could be the problem is,
all protected endpoints in strapi take Authorization: Bearer token Headers but in this, it’s automatically passed with Set-Cookie, thus for strapi endpoints no headers are passed.
the solution could be, somethings from which before the request is hit to the /users/me, Cookie from Headers are taken then placed in Authorization and then hit the API, all this in the backend
Something like this mentioned here,
How to put JWT’s in server-side cookies using the Strapi user-permissions plugin
on the Modify Auth Handler