'Strapi 4 extend auth.callback login function give 405 routes
I'm trying to add a refresh token to strapi 4 login function when I'm login the user. I've followed this tutorial, which is done on v3. Tutorial link
I'm using Strapi 4 extensions and I modified the strapi-server.js file in ==> src/extensions/users-permissions/strapi-server.js
As explained in the tutorial, I copy/paste all functions of the controller found here (I've only tried callback for the moment)strapi github repo
I've change some path for the require to work, and I the callback is working as before when the user logs in, and I also get my token version 'tkv' and the refresh token id as in the tutorial.
I have 1 question and 1 issue.
Is there a way to avoid duplicating these core functions ? I only want to add a refresh token to the end result.
I've created two new routes to refresh and revoke the token as explained. But, even if I give the authorisations in strapi backend, I still get a "405" Method not allowed when I call the endpoint.
Something I dont understand is that in the default file of strapi-server.js, we have a demo code for the route.
// Original demo code in the existing strapi-server.js
plugin.policies[newPolicy] = (ctx) => {};
plugin.routes.push({
method: 'GET',
path: '/route-path',
handler: 'controller.action',
});
If I push the new routes using the example, I get an error, which says that plugin.routes... is not a function
If I change the routes like this, the routes are correctly added :
plugin.routes['content-api'].routes.push({
method: 'POST',
path: '/auth/refreshToken',
handler: 'auth.refreshToken',
},{
method: 'POST',
path: '/auth/revokeToken',
handler: 'auth.revokeToken',
})
Here, I get my routes added to the backend, but when I look in strapi backend roles&permissions, the endpoint path of the methods are "/api/users-permissions/auth/refreshToken" or "/api/users-permissions/auth/revokeToken". I don't understand why the controller is added.
If I call these endpoint, I get a 400 error. If I call these endpoint removing the "users-permissions" in the endpoint path, I get a 405.
I don't know where to look at, to correct this to get my tokens. Thank you all for you help.
Regards,
Fabien
Solution 1:[1]
I am not sure, but looks like the core functions have to be replicated
Working code for me as below
plugin.controllers.auth['refreshToken'] = async (ctx) => {
const params = _.assign(ctx.request.body);
// Params should consist of:
// * token - string - jwt refresh token
// * renew - boolean - if true, also return an updated refresh token. // Parse Token
try {
// Unpack refresh token
const {tkv, iat, exp, sub} = await strapi.plugins["users-permissions"].services.jwt.verify(params.token); // Check if refresh token has expired
if (Date.now() / 1000 > exp) return ctx.badRequest(null, "Expired refresh token"); // fetch user based on subject
const user = await strapi.query('plugin::users-permissions.user').findOne({where:{ id: sub }}); // Check here if user token version is the same as in refresh token
// This will ensure that the refresh token hasn't been made invalid by a password change or similar.
if (tkv !== user.tokenVersion) return ctx.badRequest(null, "Refresh token is invalid"); // Otherwise we are good to go.
ctx.send({
jwt: strapi.plugins["users-permissions"].services.jwt.issue({
id: user.id,
}),
refresh: params.renew ? generateRefreshToken(user) : null
});
} catch (e) {
return ctx.badRequest(null, "Invalid token");
}
}
plugin.controllers.auth['revoke'] = async (ctx) => {
const params = _.assign(ctx.request.body);
const userService = getService('user');
// Params should consist of:
// * token - string - jwt refresh token // Parse Token
try {
// Unpack refresh token
const {tkv, iat, exp, sub} = await strapi.plugins["users-permissions"].services.jwt.verify(params.token); // Check if refresh token has expired
if (Date.now() / 1000 > exp) return ctx.badRequest(null, "Expired refresh token"); // fetch user based on subject
const user = await strapi.query('plugin::users-permissions.user').findOne({where:{ id: sub }}); // Check here if user token version is the same as in refresh token
// This will ensure that the refresh token hasn't been made invalid by a password change or similar.
if (tkv !== user.tokenVersion) return ctx.badRequest(null, "Refresh token is invalid"); // Update the user.
const tokenVersion = user.tokenVersion + 1;
await userService.edit(sub, {
tokenVersion: tokenVersion
});
ctx.send({
confirmed: true,
});
} catch (e) {
return ctx.badRequest(null, "Invalid token");
}
}
plugin.routes['content-api'].routes.push({
"method": "POST",
"path": "/auth/refreshToken",
"handler": "auth.refreshToken",
"config": {
"policies": [],
"prefix": ""
}
});
plugin.routes['content-api'].routes.push({
"method": "POST",
"path": "/auth/revoke",
"handler": "auth.revoke",
"config": {
"policies": [],
"prefix": ""
}
});
Calling /api/auth/refreshToken and /api/auth/revoke works fine afters
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
