Implementing Authentication

1. Validating JWT Tokens

Example: JWT verification middleware

import jwt from "jsonwebtoken";

async function verifyJWT(authHeader) {
  if (!authHeader?.startsWith("Bearer ")) return null;
  try {
    const payload = jwt.verify(authHeader.slice(7), process.env.JWT_SECRET, {
      algorithms: ["RS256"], audience: "api", issuer: "auth-service"
    });
    return await db.user.findUnique({ where: { id: payload.sub } });
  } catch { return null; }
}

2. Adding User to Context

StepDetail
Extract tokenAuthorization header (Bearer) or cookie
VerifyCheck signature, expiry, audience
HydrateOptionally fetch full user from DB
Attachcontext.user

3. Protecting Resolvers

Example: Auth helper

function requireAuth(ctx) {
  if (!ctx.user) throw new GraphQLError("Unauthenticated", { extensions: { code: "UNAUTHENTICATED" } });
  return ctx.user;
}

Mutation: { createPost: (_, { input }, ctx) => { const u = requireAuth(ctx); ... } }

4. Creating Auth Directives

DirectiveBehavior
@authRequire any authenticated user
@auth(requires: ROLE)Require specific role
@publicMark as bypassing auth

5. Handling Unauthenticated Requests

ApproachDetail
Throw UNAUTHENTICATEDFor required fields
Return nullFor optional viewer
HTTP 401Set via extensions.http (Yoga/v4)

6. Implementing Login Mutation

Example: Login

login: async (_, { email, password }, { db }) => {
  const user = await db.user.findUnique({ where: { email } });
  if (!user || !(await bcrypt.compare(password, user.passwordHash))) {
    return { __typename: "InvalidCredentials", message: "Invalid email or password" };
  }
  return { __typename: "LoginSuccess", user, token: signJWT(user), refreshToken: signRefresh(user) };
}

7. Implementing Logout Mutation

StrategyDetail
Stateless JWTClient discards token; server can't revoke
Token blocklistAdd jti to Redis until exp
Refresh token rotationInvalidate refresh in DB
Cookie-basedClear-Site-Data header

8. Refreshing Access Tokens

Example: Refresh mutation

type Mutation {
  refreshAccessToken(refreshToken: String!): TokenPair!
}
type TokenPair { accessToken: String!, refreshToken: String!, expiresIn: Int! }

9. Using Session-based Auth

PatternDetail
HTTP-only cookieSession id stored in Redis/DB
CSRF protectionSameSite=Strict, custom header
Server revocationEasy — delete server-side session

10. Implementing Social Auth

ProviderLibrary
OAuth/OIDCpassport, NextAuth, Auth.js, Authelia
FederatedAuth0, Clerk, Cognito, Firebase Auth
GraphQL flowMutation exchanges OAuth code → JWT