如何在Strawberry GraphQL输入字段上配置权限控制?
Strawberry输入字段权限控制实现方案
Strawberry官方的permission_classes参数仅对输出类型(@strawberry.type)的字段生效,输入类型(@strawberry.input)的字段不会触发权限校验,目前官方暂无内置的输入字段权限控制功能,可通过以下自定义方式实现需求:
方案一:Resolver内手动校验权限
在接收输入参数的resolver中,直接检查用户权限与传入的字段值,若用户无权限却尝试修改受保护字段则抛出错误。
示例代码:
from typing import Optional import strawberry from strawberry.types import Info # 定义输入类型 @strawberry.input class UpdateSomeModelInput: id: strawberry.ID login: Optional[str] = None # 允许不传,传了则校验权限 # 示例权限判断逻辑 def has_modify_login_permission(user) -> bool: return user.is_admin # 假设仅管理员可修改login字段 @strawberry.type class Mutation: @strawberry.mutation def update_some_model(self, info: Info, input: UpdateSomeModelInput) -> "SomeModel": user = info.context["user"] # 校验权限:用户无权限且传入了login字段则报错 if not has_modify_login_permission(user) and input.login is not None: raise PermissionError("无权限修改login字段") # 执行后续更新逻辑 model = get_model_by_id(input.id) if input.login is not None: model.login = input.login save_model(model) return SomeModel(id=model.id, login=model.login) @strawberry.type class SomeModel: id: strawberry.ID login: str
方案二:利用Strawberry扩展统一校验
通过自定义Extension,在输入参数解析阶段拦截并校验权限,实现集中式的输入字段权限控制,避免重复代码。
示例代码:
import strawberry from strawberry.extensions import Extension from strawberry.types import Info class InputFieldPermissionExtension(Extension): def on_input_value_parsed(self, info: Info, input_value: object, type_name: str): # 针对特定输入类型做校验 if type_name == "UpdateSomeModelInput": user = info.context["user"] # 检查用户权限与传入字段 if not user.is_admin and hasattr(input_value, "login") and input_value.login is not None: raise PermissionError("无权限修改login字段") return input_value # 定义输入类型 @strawberry.input class UpdateSomeModelInput: id: strawberry.ID login: Optional[str] = None # 定义Schema时添加扩展 schema = strawberry.Schema( mutation=Mutation, extensions=[InputFieldPermissionExtension()] )
方案对比
- 手动校验:实现简单,适合单个resolver的场景,但权限逻辑分散,维护成本高。
- 扩展校验:集中管理权限规则,适合多输入类型、多resolver的场景,代码更整洁,但需要熟悉Strawberry的扩展机制。
内容的提问来源于stack exchange,提问作者Oleg Korkeshko
相关产品推荐
相关产品推荐

