将新字段添加到 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");
  }
}