我正在寻找一种在 Graphql 设置中集中授权的方法。 这是我面临的问题的完整背景
我有一个超级图和两个子图,我们称它们为帖子和用户。
帖子对所有人公开,而用户对管理员或有权查看用户的人来说是私有的。 另一个子图将被实现,我们称之为产品,这个子图中的数据也将是某些用户私有的。这意味着现在我需要在我的新子图中实现授权。 所以我想知道是否可以从我的用户那里获取授权,将其移至我的超级图,然后在我的销售子图中重用它。
我现在尝试的是在对象类型上使用的指令,该指令在每个子图中都可以正常工作,而当我将其移动到我的超级图时,它就不再起作用了。 这是 github 中该项目的链接:https://github.com/rezaerami/gql-federation
长话短说,我想让我的子图授权不可知,只需放置后面的 IP 保护,并且我的子图强制执行解析器的权限。
因为使用指令不可能做我想做的事,所以我决定使用 willSendRequest 钩子 使用一个根据用户权限检查查询权限的函数我设法做到了
这是我的检查权限代码
const {parse} = require("graphql/language");
const permissions = {
query: {
product: ["admin", "user"],
seller: ["admin"],
}
}
const checkPermission = (req, context) => {
const document = parse(req.query);
const unauthorizedOperations = [];
document.definitions.forEach(definition => {
definition.selectionSet.selections.forEach(selection => {
if (permissions?.[definition.operation]?.[selection.name.value]) {
if (!permissions[definition.operation][selection.name.value].some(permission => context.user.role.includes(permission))) {
unauthorizedOperations.push({
operation: definition.operation,
selection: selection.name.value,
})
}
}
})
})
if (unauthorizedOperations.length) {
throw new Error(`Unauthorized permissions for ${unauthorizedOperations[0].operation}.${unauthorizedOperations[0].selection}`);
}
}
module.exports = checkPermission
然后我在 willSendRequest 上添加了这一行
checkPermission(request, context)
它并不理想,因为它基本上是一个技巧,并且不使用 graphql 的内置功能,但它做了我想做的事情!