字段守卫 (Field Guard)
你可以为Object
, SimpleObject
, ComplexObject
和Subscription
的字段定义守卫
,它将在调用字段的 Resolver 函数前执行,如果失败则返回一个错误。
#![allow(unused)] fn main() { extern crate async_graphql; use async_graphql::*; #[derive(Eq, PartialEq, Copy, Clone)] enum Role { Admin, Guest, } struct RoleGuard { role: Role, } impl RoleGuard { fn new(role: Role) -> Self { Self { role } } } impl Guard for RoleGuard { async fn check(&self, ctx: &Context<'_>) -> Result<()> { if ctx.data_opt::<Role>() == Some(&self.role) { Ok(()) } else { Err("Forbidden".into()) } } } }
用guard
属性使用它:
#![allow(unused)] fn main() { extern crate async_graphql; use async_graphql::*; #[derive(Eq, PartialEq, Copy, Clone)] enum Role { Admin, Guest, } struct RoleGuard { role: Role, } impl RoleGuard { fn new(role: Role) -> Self { Self { role } } } impl Guard for RoleGuard { async fn check(&self, ctx: &Context<'_>) -> Result<()> { todo!() } } #[derive(SimpleObject)] struct Query { /// 只允许 Admin 访问 #[graphql(guard = "RoleGuard::new(Role::Admin)")] value1: i32, /// 允许 Admin 或者 Guest 访问 #[graphql(guard = "RoleGuard::new(Role::Admin).or(RoleGuard::new(Role::Guest))")] value2: i32, } }
从参数中获取值
有时候守卫需要从字段参数中获取值,你需要像下面这样在创建守卫时传递该参数值:
#![allow(unused)] fn main() { extern crate async_graphql; use async_graphql::*; struct EqGuard { expect: i32, actual: i32, } impl EqGuard { fn new(expect: i32, actual: i32) -> Self { Self { expect, actual } } } impl Guard for EqGuard { async fn check(&self, _ctx: &Context<'_>) -> Result<()> { if self.expect != self.actual { Err("Forbidden".into()) } else { Ok(()) } } } struct Query; #[Object] impl Query { #[graphql(guard = "EqGuard::new(100, value)")] async fn get(&self, value: i32) -> i32 { value } } }