Open
Description
I'm currently using something like this
// This will later be passed to GraphQL resolvers via the schema context
pub struct AuthContext {
pub claims: Option<Claims>,
}
impl AuthContext {
// Helper function to ensure authorized access in Gql resolvers
pub fn require_auth(&self) -> async_graphql::Result<&Claims> {
self.claims
.as_ref()
.ok_or_else(|| async_graphql::Error::new("Unauthorized"))
}
}
...
#[async_graphql::Object]
impl UserMutations {
async fn create_user(&self, ctx: &Context<'_>, input: CreateUserInput) -> Result<GqlUser> {
// Require authentication for this mutation
ctx.data::<AuthContext>()?.require_auth()?;
...
}
}
to enforce authentication on my mutation(s).
I now wanted to switch to using an @authorized
directive, so I added something like
pub struct AuthDirective;
#[async_trait::async_trait]
impl CustomDirective for AuthDirective {
async fn resolve_field(
&self,
ctx: &Context<'_>,
resolve: ResolveFut<'_>,
) -> ServerResult<Option<Value>> {
// Ensure user is authenticated
let auth_ctx = ctx
.data::<AuthContext>()
.map_err(|err| ServerError::new(err.message, None))?;
auth_ctx
.require_auth()
.map_err(|err| ServerError::new(err.message, None))?;
resolve.await
}
}
#[Directive(location = "Field")]
pub fn authenticated() -> impl CustomDirective {
AuthDirective
}
and modified my mutation signature to
#[graphql(directive = authenticated::apply())]
async fn create_user(&self, ctx: &Context<'_>, input: CreateUserInput) -> Result<GqlUser> {
I've also added it to my schema with .directive(authenticated)
But that doesn't 50BC work. Unfortunately the documentation on this is not much help either, as it does not show how to use an Executable directive (only how to add it to the schema). The relevant test also only shows how to add it to the schema, not how to annotate a mutation with the directive.
Any help getting such a custom directive to enforce authentication working? Thanks in advance :)