DGraph @auth指令未正常生效?求技术排查
问题分析与解决方案
核心问题
你的@auth规则存在两个关键问题,导致权限控制未按预期生效:
- 规则类型错误:当前使用的
query规则仅用于验证「用户是否有权限执行查询操作」,而非「过滤查询返回的结果」。因此只要规则验证通过(比如JWT包含ID字段),主查询会返回所有设备。 - 变量映射与格式不匹配:规则中
$ID定义为数组类型[ID!],但如果JWT中的ID是字符串而非数组,或未正确放置在指定的Namespace下,会导致规则逻辑失效。
修复步骤
1. 修正@auth规则(改为结果过滤模式)
将query规则替换为filter规则,直接限制queryDevices返回的设备只能是JWT中指定ID的条目:
type Device @auth( query: { filter: { id: { in: "$ID" } } } ) { id: ID! displayName: String! isOnline: Boolean! lastSeen: DateTime! } # Dgraph.Authorization {"VerificationKey": "password123", "Header": "X-Auth", "Namespace": "https://app.me/jwt/claims", "Algo": "HS256"}
这个规则的作用是:仅允许用户查询ID在JWT的ID数组中的设备。
2. 确保JWT的Payload格式正确
因为你指定了Namespace为https://app.me/jwt/claims,所以JWT的Payload必须将ID字段放在该命名空间下,且为数组类型(匹配规则中的[ID!]):
{ "https://app.me/jwt/claims": { "ID": ["你的设备ID"] }, "exp": 1735689600 # 替换为有效过期时间 }
- 注意:
ID必须是数组,即使只有一个设备ID也要用["xxx"],不能直接写字符串。 - 签名算法选择HS256,密钥填
password123,确保与Schema中的配置一致。
3. 验证规则逻辑
- 当JWT中包含有效设备ID时,
queryDevices只会返回该ID的设备。 - 当JWT中包含无效ID时,
queryDevices会返回空数组(因为没有匹配的设备)。 - 当JWT中没有
ID字段时,会直接拒绝查询(符合你当前的现象)。
额外说明
如果坚持使用query规则的方式(验证权限+过滤结果),需要确保规则的查询结果与主查询关联,正确写法如下:
type Device @auth( query: { rule: """ query ($ID: [ID!]) { queryDevices(filter: {id: $ID}) { id } } """ } ) { # ... 字段定义 }
这种写法中,规则的查询结果会作为主查询的过滤条件,但实际使用中filter规则更简洁直观,推荐优先使用。
内容的提问来源于stack exchange,提问作者leonhma
相关产品推荐
相关产品推荐

