Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generic auth resolveUserFn being called for Public Fields in protect-granular Mode #2364

Open
ethdev279 opened this issue Jan 11, 2025 Discussed in #2363 · 1 comment
Open

Comments

@ethdev279
Copy link

Discussed in #2363

Originally posted by ethdev279 January 11, 2025

I’m using @envelop/generic-auth in my GraphQL Yoga server, following this example. I’ve set mode to protect-granular, expecting the resolveUserFn to only be called for fields marked with the @authenticated directive. However, I noticed that resolveUserFn is being called for all fields, including public fields that don’t require authentication.

This behavior adds unnecessary overhead for fields that don’t need user resolution or validation.

What I was expecting:

In protect-granular mode:

  • resolveUserFn should only be invoked for fields marked with the @authenticated directive.
  • Public fields should bypass user resolution and validation.

Actual Behavior

  • resolveUserFn is executed for all fields, including public fields, leading to unnecessary overhead.

Reproduction

  1. Schema:

    directive @authenticated on FIELD_DEFINITION
    
    type Query {
      requiresAuth: String @authenticated
      public: String
    }
  2. Plugin setup in GraphQL Yoga:

    useGenericAuth({
      mode: 'protect-granular',
      async resolveUserFn(context) {
        const token = context.request.headers.get('x-authorization');
        // further validations: decoding, getting user deails from db e.t.c.
        return token ?? null;
      },
    });
  3. Query:

    query {
      public
    }
  4. Observe that resolveUserFn is called for the public field.

any thoughts on this?

@EmrysMyrddin
Copy link
Collaborator

Hi!

This is the expected behavior. The user is always fetched at context building time. The plugin then extends the context with the resolved user to make it available for all resolvers or other plugins by storing the user in the context.

The protect-granular implies that the validateUser function will be called only for marked fields. Which means you can return null from resolveUserFn if their is no authenticated user for a request, public fields will still be resolvable.

Don't hesitate to ask more question if my explanation is not clear enough!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants