将新字段添加到 strapi 后端的上下文变量以进行用户管理
Add new fields to context variable in strapi backend for user management
我正在使用 strapi 作为后端并在前端做出反应。所以用例是用户将注册并且该注册将使用 auth0 完成。我已经为注册用户定义了一些角色,如 auth0 所示
Roles based on plan taken by user
const _ = require("lodash");
const axios = require("axios");
const jwt = require("../jwt");
module.exports = async (ctx, next) => {
let role;
if (ctx.state.user) {
// request is already authenticated in a different way
return next();
}
try {
const tokenInfo = await axios({ method: "post",
url: `${process.env.AUTH0_URL}/userinfo`,
headers: { Authorization: ctx.request.header.authorization,
},
});
let user_id = tokenInfo.data.sub;
var config = { method: "get",
url: `${process.env.AUTH0_URL}/api/v2/users/${user_id}/roles`,
headers: {Authorization: `Bearer ${jwt.jwtSecret}`,
},
};
axios(config).then(function (response) {
ctx.state.roles = response.data[0].name; // This part does not work in the next policy as ctx.state.role gives undefined in route specific policy
}).catch(function (error) {
console.log(error);
});
// console.log(tokenInfo.data, "tokeninfo");
if (tokenInfo && tokenInfo.data) {
return await next();
}
} catch (err) {
console.log(err.message);
return handleErrors(ctx, err, "unauthorized");
}
目前,这些将仅在此处进行管理。现在我有一个集合,其中有一些研究文章,只能根据已分配的计划用户访问。为了保护路由和 strapi 访问,我在 strapi 中安装了用户权限插件,并使用全局策略管理用户信息,如图所示
Project Structure
.所以这是我在每条路线上检查用户信息的代码
现在有两种方法可以解决我的问题。首先,我从 userInfo 路由读取了 tokenInfo 数据,但不幸的是 auth0 没有返回分配的角色。它只返回标准数据,如
"name": "ansh5@gmail.com",
"nickname": "ansh5",
"picture": "https://s.gravatar.com/avatar/6fdb83f10321dd7712ac2457b11ea34e?
s=480&r=pg&d=https%3A%2F%2Fcdn.auth0.com%2Favatars%2Fan.png",
"updated_at": "2021-07-19T08:03:50.461Z",
"user_id": "auth0|60ec0b3721224b0078ac95f4",
因此,为了获得用户角色,我使用了另一个 API 并使用我的 auth0 帐户对其进行了配置。
${process.env.AUTH0_URL}/api/v2/users/${user_id}/角色
我得到了正确的回应,但是当我做这个作业时。
ctx.state.roles = response.data[0].name;
我的路由特定策略中的 ctx.state.roles 未定义。有没有人知道我们如何一起管理 strapi 和 auth0。
是的,这是因为 axios
调用本质上是 asynchronous
。因此,根据您的代码,axios
将尝试通过网络调用获取用户信息,但 strapi
不会真正等待响应。相反,它只会前进到下一个策略,从而导致未定义的用户角色。要解决此问题,您需要 await
以获取来自 axios
的 api 响应。试试下面的代码:
const axios = require("axios");
const jwt = require("../jwt");
module.exports = async (ctx, next) => {
let role;
if (ctx.state.user) {
// request is already authenticated in a different way
return next();
}
try {
const tokenInfo = await axios({
method: "post",
url: `${process.env.AUTH0_URL}/userinfo`,
headers: {
Authorization: ctx.request.header.authorization,
},
});
let user_id = tokenInfo.data.sub;
var config = {
method: "get",
url: `${process.env.AUTH0_URL}/api/v2/users/${user_id}/roles`,
headers: {
Authorization: `Bearer ${jwt.jwtSecret}`,
},
};
const resp = await axios(config);
ctx.state.roles = response.data[0].name;
console.log(ctx.state.roles);
// console.log(tokenInfo.data, "tokeninfo");
if (tokenInfo && tokenInfo.data) {
return await next();
}
} catch (err) {
console.log(err.message);
return handleErrors(ctx, err, "unauthorized");
}
}
我正在使用 strapi 作为后端并在前端做出反应。所以用例是用户将注册并且该注册将使用 auth0 完成。我已经为注册用户定义了一些角色,如 auth0 所示 Roles based on plan taken by user
const _ = require("lodash");
const axios = require("axios");
const jwt = require("../jwt");
module.exports = async (ctx, next) => {
let role;
if (ctx.state.user) {
// request is already authenticated in a different way
return next();
}
try {
const tokenInfo = await axios({ method: "post",
url: `${process.env.AUTH0_URL}/userinfo`,
headers: { Authorization: ctx.request.header.authorization,
},
});
let user_id = tokenInfo.data.sub;
var config = { method: "get",
url: `${process.env.AUTH0_URL}/api/v2/users/${user_id}/roles`,
headers: {Authorization: `Bearer ${jwt.jwtSecret}`,
},
};
axios(config).then(function (response) {
ctx.state.roles = response.data[0].name; // This part does not work in the next policy as ctx.state.role gives undefined in route specific policy
}).catch(function (error) {
console.log(error);
});
// console.log(tokenInfo.data, "tokeninfo");
if (tokenInfo && tokenInfo.data) {
return await next();
}
} catch (err) {
console.log(err.message);
return handleErrors(ctx, err, "unauthorized");
}
目前,这些将仅在此处进行管理。现在我有一个集合,其中有一些研究文章,只能根据已分配的计划用户访问。为了保护路由和 strapi 访问,我在 strapi 中安装了用户权限插件,并使用全局策略管理用户信息,如图所示
Project Structure
.所以这是我在每条路线上检查用户信息的代码
现在有两种方法可以解决我的问题。首先,我从 userInfo 路由读取了 tokenInfo 数据,但不幸的是 auth0 没有返回分配的角色。它只返回标准数据,如
"name": "ansh5@gmail.com",
"nickname": "ansh5",
"picture": "https://s.gravatar.com/avatar/6fdb83f10321dd7712ac2457b11ea34e?
s=480&r=pg&d=https%3A%2F%2Fcdn.auth0.com%2Favatars%2Fan.png",
"updated_at": "2021-07-19T08:03:50.461Z",
"user_id": "auth0|60ec0b3721224b0078ac95f4",
因此,为了获得用户角色,我使用了另一个 API 并使用我的 auth0 帐户对其进行了配置。
${process.env.AUTH0_URL}/api/v2/users/${user_id}/角色
我得到了正确的回应,但是当我做这个作业时。
ctx.state.roles = response.data[0].name;
我的路由特定策略中的 ctx.state.roles 未定义。有没有人知道我们如何一起管理 strapi 和 auth0。
是的,这是因为 axios
调用本质上是 asynchronous
。因此,根据您的代码,axios
将尝试通过网络调用获取用户信息,但 strapi
不会真正等待响应。相反,它只会前进到下一个策略,从而导致未定义的用户角色。要解决此问题,您需要 await
以获取来自 axios
的 api 响应。试试下面的代码:
const axios = require("axios");
const jwt = require("../jwt");
module.exports = async (ctx, next) => {
let role;
if (ctx.state.user) {
// request is already authenticated in a different way
return next();
}
try {
const tokenInfo = await axios({
method: "post",
url: `${process.env.AUTH0_URL}/userinfo`,
headers: {
Authorization: ctx.request.header.authorization,
},
});
let user_id = tokenInfo.data.sub;
var config = {
method: "get",
url: `${process.env.AUTH0_URL}/api/v2/users/${user_id}/roles`,
headers: {
Authorization: `Bearer ${jwt.jwtSecret}`,
},
};
const resp = await axios(config);
ctx.state.roles = response.data[0].name;
console.log(ctx.state.roles);
// console.log(tokenInfo.data, "tokeninfo");
if (tokenInfo && tokenInfo.data) {
return await next();
}
} catch (err) {
console.log(err.message);
return handleErrors(ctx, err, "unauthorized");
}
}