如何将 JWT 令牌从 Headers Set-Cookie 传递到 Strapi 中的授权 Headers
How to pass JWT token from Headers Set-Cookie to Authorization Headers in Strapi
[details="系统信息"]
- Strapi 版本:4.1**
- 操作系统:Windows11
- 数据库:Postgress
- 节点版本:
- NPM 版本:
- 纱线版本:
[/详情]
我想要用户的角色,所以我通过添加 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;
};
所以它看起来像这样,现在从服务器端添加 cookie,即仅 HTTP,我添加了我的自定义端点(“/auth/login”)
src/api/custom
const axios = require("axios");
module.exports = {
async index(ctx) {
const { body } = ctx.request;
const absoluteURL = `http://${hostname}:${strapi.config.server.port}`;
const sanitizeOutput = (user) => {
const {
password,
resetPasswordToken,
confirmationToken,
...sanitizedUser
} = user;
return sanitizedUser;
};
try {
console.log("Tryin to login");
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);
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);
}
}
};
现在从我的前端调用 /auth/login,它 returns 只是和用户并从服务器设置 cookie,即仅 HTTP,现在当我调用 /users/me,它说未经授权
我知道可能是什么问题,
strapi 中所有受保护的端点都采用授权:不记名令牌 Headers,但在此情况下,它会自动通过 Set-Cookie 传递,因此对于 strapi 端点,不会传递 headers。
解决方案可能是,在将请求命中 /users/me 之前,从 Headers 获取 Cookie,然后将其放入授权中,然后命中 API,所有这在后端
这里提到了类似的东西,
How to put JWT's in server-side cookies using the Strapi user-permissions plugin
在修改授权处理程序上
我试过了,但似乎 permissions.js 并且文章中提到的所有内容都是 v3.** 因为提到的参考链接是 v3.
所以在做了一些研究之后,我找到了为此做些什么。
所以基本上,我 setup-ed 一个中间件,它的工作是从 header cookie 中获取 jwt 令牌并设置 Authorization: Bearer token
回答
创建自定义中间件
./src/middlewares/TokenPlacer.js
(文件名可自选)
module.exports = () => {
return async (ctx, next) => {
const cookies = ctx.request.header.cookie || false;
if (cookies) {
let token = cookies
.split(";")
.find((c) => c.trim().startsWith("jwt="))
.split("=")[1];
if (token) {
ctx.request.header.authorization = `Bearer ${token}`;
}
}
await next();
};
};
我在 cookie 中将我的 JWT 令牌保存为 jwt
,因此请相应地更改它!
加载自定义中间件
然后在./config/middleware.js
中找到中间件文件
如果您没有使用任何中间件或自定义任何东西,那么它应该看起来像这样
module.exports = [
"strapi::errors",
"strapi::security",
"strapi::cors",
"strapi::poweredBy",
"strapi::logger",
"strapi::query",
"strapi::body",
"strapi::session",
"strapi::favicon",
"strapi::public",
];
现在我们需要告诉 Strapi 加载我们的自定义中间件
所以只需在末尾添加 "global::__YOUR__MIDDLEWARE_FILENAME__",
,所以对我来说 "global::TokenPlacer",
,所以现在看起来像这样
module.exports = [
"strapi::errors",
"strapi::security",
"strapi::cors",
"strapi::poweredBy",
"strapi::logger",
"strapi::query",
"strapi::body",
"strapi::session",
"strapi::favicon",
"strapi::public",
"global::TokenPlacer",
];
Learn more about Strapi Middleware and customize accordingly - Official Strapi Docs v4
[details="系统信息"]
- Strapi 版本:4.1**
- 操作系统:Windows11
- 数据库:Postgress
- 节点版本:
- NPM 版本:
- 纱线版本: [/详情]
我想要用户的角色,所以我通过添加 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;
};
所以它看起来像这样,现在从服务器端添加 cookie,即仅 HTTP,我添加了我的自定义端点(“/auth/login”)
src/api/custom
const axios = require("axios");
module.exports = {
async index(ctx) {
const { body } = ctx.request;
const absoluteURL = `http://${hostname}:${strapi.config.server.port}`;
const sanitizeOutput = (user) => {
const {
password,
resetPasswordToken,
confirmationToken,
...sanitizedUser
} = user;
return sanitizedUser;
};
try {
console.log("Tryin to login");
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);
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);
}
}
};
现在从我的前端调用 /auth/login,它 returns 只是和用户并从服务器设置 cookie,即仅 HTTP,现在当我调用 /users/me,它说未经授权
我知道可能是什么问题, strapi 中所有受保护的端点都采用授权:不记名令牌 Headers,但在此情况下,它会自动通过 Set-Cookie 传递,因此对于 strapi 端点,不会传递 headers。
解决方案可能是,在将请求命中 /users/me 之前,从 Headers 获取 Cookie,然后将其放入授权中,然后命中 API,所有这在后端
这里提到了类似的东西, How to put JWT's in server-side cookies using the Strapi user-permissions plugin 在修改授权处理程序上
我试过了,但似乎 permissions.js 并且文章中提到的所有内容都是 v3.** 因为提到的参考链接是 v3.
所以在做了一些研究之后,我找到了为此做些什么。
所以基本上,我 setup-ed 一个中间件,它的工作是从 header cookie 中获取 jwt 令牌并设置 Authorization: Bearer token
回答
创建自定义中间件
./src/middlewares/TokenPlacer.js
(文件名可自选)
module.exports = () => {
return async (ctx, next) => {
const cookies = ctx.request.header.cookie || false;
if (cookies) {
let token = cookies
.split(";")
.find((c) => c.trim().startsWith("jwt="))
.split("=")[1];
if (token) {
ctx.request.header.authorization = `Bearer ${token}`;
}
}
await next();
};
};
我在 cookie 中将我的 JWT 令牌保存为 jwt
,因此请相应地更改它!
加载自定义中间件
然后在./config/middleware.js
中找到中间件文件
如果您没有使用任何中间件或自定义任何东西,那么它应该看起来像这样
module.exports = [
"strapi::errors",
"strapi::security",
"strapi::cors",
"strapi::poweredBy",
"strapi::logger",
"strapi::query",
"strapi::body",
"strapi::session",
"strapi::favicon",
"strapi::public",
];
现在我们需要告诉 Strapi 加载我们的自定义中间件
所以只需在末尾添加 "global::__YOUR__MIDDLEWARE_FILENAME__",
,所以对我来说 "global::TokenPlacer",
,所以现在看起来像这样
module.exports = [
"strapi::errors",
"strapi::security",
"strapi::cors",
"strapi::poweredBy",
"strapi::logger",
"strapi::query",
"strapi::body",
"strapi::session",
"strapi::favicon",
"strapi::public",
"global::TokenPlacer",
];
Learn more about Strapi Middleware and customize accordingly - Official Strapi Docs v4