Bird
Raised Fist0
GraphQLquery~10 mins

Directive-based authorization in GraphQL - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Directive-based authorization
Client sends GraphQL query
↓
GraphQL server parses query
↓
Server checks for authorization directives
↓
Evaluate directive conditions
↓
Allow field
↓
Return data
↓
Send response
The server reads the query, checks authorization directives on fields, allows or denies access accordingly, then returns data or errors.
Execution Sample
GraphQL
query {
  user {
    id
    email @auth(role: "ADMIN")
  }
}
A query requesting user id and email, where email requires ADMIN role authorization.
Execution Table
StepFieldDirective CheckUser RoleAuthorization ResultAction
1userNo directiveUSERAllowedResolve user data
2user.idNo directiveUSERAllowedReturn id value
3user.email@auth(role: "ADMIN")USERDeniedReturn error or null for email
4Response---Send user id and error/null for email
💡 Authorization directive on email fails for USER role, so email is not returned.
Variable Tracker
VariableStartAfter Step 1After Step 2After Step 3Final
usernull{id: 1, email: 'a@b.com'}{id: 1, email: 'a@b.com'}{id: 1, email: 'a@b.com'}{id: 1, email: null}
user.idnull1111
user.emailnulla@b.coma@b.comdeniednull
Key Moments - 2 Insights
Why is the email field not returned even though it exists in the data?
Because the email field has an @auth directive requiring ADMIN role, and the user role is USER, so authorization fails (see execution_table step 3).
What happens if a field has no authorization directive?
Fields without directives are allowed by default, so their data is returned normally (see execution_table steps 1 and 2).
Visual Quiz - 3 Questions
Test your understanding
Look at the execution table, what is the authorization result for the user.id field at step 2?
AAllowed
BDenied
CNot checked
DError
💡 Hint
Check the 'Authorization Result' column for step 2 in the execution_table.
At which step does the authorization directive cause a denial?
AStep 1
BStep 2
CStep 3
DStep 4
💡 Hint
Look for the step where 'Authorization Result' is 'Denied' in the execution_table.
If the user role was ADMIN instead of USER, how would the authorization result for user.email change?
AIt would still be Denied
BIt would be Allowed
CIt would be Not checked
DIt would cause an error
💡 Hint
Refer to the 'Directive Check' and 'User Role' columns in the execution_table step 3.
Concept Snapshot
Directive-based authorization in GraphQL:
- Use directives like @auth(role: "ADMIN") on fields
- Server checks user role against directive
- If authorized, field data is returned
- If denied, field returns error or null
- Fields without directives are allowed by default
Full Transcript
Directive-based authorization in GraphQL works by adding special instructions called directives to fields in a query. When a client sends a query, the server reads it and looks for these directives. For each field with a directive, the server checks if the user has the required role. If yes, the field's data is returned. If not, the field returns an error or null. Fields without directives are returned normally. For example, if a field requires ADMIN role but the user is USER, that field's data is not returned. This process ensures only authorized users see sensitive data.

Practice

(1/5)
1. What is the main purpose of using directive-based authorization in GraphQL?
easy
A. To control who can access certain data or operations
B. To speed up query execution
C. To format the output data
D. To create new database tables

Solution

  1. Step 1: Understand directive-based authorization

    Directive-based authorization adds rules to GraphQL fields or types to restrict access based on user roles or permissions.
  2. Step 2: Identify the main goal

    The main goal is to control access to data or operations, ensuring only authorized users can see or change certain information.
  3. Final Answer:

    To control who can access certain data or operations -> Option A
  4. Quick Check:

    Authorization controls access = B [OK]
Hint: Authorization directives control access permissions [OK]
Common Mistakes:
  • Confusing authorization with performance optimization
  • Thinking directives format data output
  • Assuming directives create database structures
2. Which of the following is the correct syntax to apply a directive named @auth requiring a role ADMIN on a GraphQL field?
easy
A. type Query { secretData: String @auth(role: ADMIN) }
B. type Query { secretData: String @auth(role: "ADMIN") }
C. type Query { secretData: String @auth(role=ADMIN) }
D. type Query { secretData: String @auth[role=ADMIN] }

Solution

  1. Step 1: Recall directive syntax in GraphQL

    Directives use parentheses with named arguments and string values in quotes, e.g., @directiveName(argName: "value").
  2. Step 2: Match the correct syntax

    type Query { secretData: String @auth(role: "ADMIN") } correctly uses @auth(role: "ADMIN") with quotes around the string role value.
  3. Final Answer:

    type Query { secretData: String @auth(role: "ADMIN") } -> Option B
  4. Quick Check:

    Directive args use parentheses and quotes = D [OK]
Hint: Directives use parentheses and quoted strings for arguments [OK]
Common Mistakes:
  • Using square brackets instead of parentheses
  • Omitting quotes around string values
  • Using equals sign without quotes
3. Given the schema snippet:
type Query {
  userProfile: User @auth(role: "USER")
}

type User {
  id: ID!
  email: String
  secretNote: String @auth(role: "ADMIN")
}

What happens when a user with role USER queries userProfile { id email secretNote }?
medium
A. The query returns only id
B. The query returns all fields including secretNote
C. The query fails with an authorization error
D. The query returns id and email, but secretNote is blocked

Solution

  1. Step 1: Analyze field-level directives

    The userProfile field requires role USER, so the user can access it. The secretNote field requires ADMIN role, which the user does not have.
  2. Step 2: Determine accessible fields

    The user can see id and email but not secretNote because of the stricter ADMIN directive on that field.
  3. Final Answer:

    The query returns id and email, but secretNote is blocked -> Option D
  4. Quick Check:

    Field directives restrict access individually = C [OK]
Hint: Field directives override parent access; check each field's role [OK]
Common Mistakes:
  • Assuming all fields inherit parent directive permissions
  • Expecting full data without role ADMIN
  • Thinking query fails instead of partial data
4. Consider this schema snippet:
type Query {
  adminData: String @auth(role: "ADMIN")
}

Which of the following fixes the error if the directive @auth is not recognized by the GraphQL server?
medium
A. Define the @auth directive in the schema with directive @auth(role: String) on FIELD_DEFINITION
B. Remove the @auth directive from the schema
C. Change @auth to @authorize without defining it
D. Rename the field adminData to adminInfo

Solution

  1. Step 1: Understand directive registration

    GraphQL requires custom directives to be declared in the schema before use, specifying their name, arguments, and locations.
  2. Step 2: Apply correct fix

    Define the @auth directive in the schema with directive @auth(role: String) on FIELD_DEFINITION correctly defines the @auth directive with a role argument and usage on field definitions, enabling the server to recognize it.
  3. Final Answer:

    Define the @auth directive in the schema with directive @auth(role: String) on FIELD_DEFINITION -> Option A
  4. Quick Check:

    Custom directives must be declared in schema = A [OK]
Hint: Declare custom directives in schema before use [OK]
Common Mistakes:
  • Removing directives without replacing authorization
  • Using undefined directive names
  • Changing field names unrelated to directive errors
5. You want to restrict access so that only users with role EDITOR or ADMIN can update posts. Which directive usage correctly applies this logic on the updatePost mutation?
hard
A. type Mutation { updatePost(id: ID!, content: String!): Post @auth(role: "EDITOR") @auth(role: "ADMIN") }
B. type Mutation { updatePost(id: ID!, content: String!): Post @auth(roles: ["EDITOR", "ADMIN"]) }
C. type Mutation { updatePost(id: ID!, content: String!): Post @auth(role_in: ["EDITOR", "ADMIN"]) }
D. type Mutation { updatePost(id: ID!, content: String!): Post @auth(role: "EDITOR" OR "ADMIN") }

Solution

  1. Step 1: Understand role list syntax in directives

    To allow multiple roles, the directive argument should accept a list (array) of roles, often named role_in or similar, depending on implementation.
  2. Step 2: Evaluate options for correct syntax

    type Mutation { updatePost(id: ID!, content: String!): Post @auth(role_in: ["EDITOR", "ADMIN"]) } uses @auth(role_in: ["EDITOR", "ADMIN"]), which correctly passes an array of roles to check for authorization.
  3. Final Answer:

    type Mutation { updatePost(id: ID!, content: String!): Post @auth(role_in: ["EDITOR", "ADMIN"]) } -> Option C
  4. Quick Check:

    Use array argument for multiple roles = A [OK]
Hint: Use array argument to list multiple allowed roles [OK]
Common Mistakes:
  • Stacking multiple @auth directives instead of one with list
  • Using invalid OR syntax inside directive argument
  • Using wrong argument name like roles instead of role_in
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard