Skip to content

NextAuth Integration

This guide explains how authentication is implemented in the Bagisto Headless storefront using NextAuth.js. We use a decoupled authentication flow where NextAuth manages the application session while communicating with the Bagisto GraphQL API for credential verification.

2.1 Implementation Architecture

2.2 Core Files & Logic

File PathPurpose
[utils/auth.ts]Defines authOptions, including the custom Credentials provider and callbacks.
[api/auth/[...nextauth]/route.ts]The NextAuth dynamic API route that handles all auth requests.
[providers/NextAuthProvider.tsx]Client-side wrapper that provides session context to the entire application.
[types/next-auth.d.ts]TypeScript definitions to extend the User and Session objects with custom fields.

2.3 Custom Credentials Provider

The storefront uses a custom credentials provider to authenticate customers directly against the Bagisto backend.

typescript
// Logic from src/utils/auth.ts
CredentialsProvider({
  name: "Credentials",
  authorize: async (credentials) => {
    // 1. Fetch from Bagisto
    const res = await bagistoFetch({
      query: CUSTOMER_LOGIN,
      variables: { input: { email, password } },
    });

    const login = res?.body?.data?.createLogin?.login;

    // 2. Validate response
    if (!login?.success) throw new Error(login?.message);

    // 3. Return user object to persist in JWT
    return {
      email: credentials.username,
      apiToken: login.apiToken,
      accessToken: login.token, // Sanctum token
    };
  },
})
typescript
// Session Persistence Logic
callbacks: {
  async jwt({ token, user }) {
    if (user) {
      token.accessToken = user.accessToken;
      token.apiToken = user.apiToken;
    }
    return token;
  },
  async session({ session, token }) {
    session.user.accessToken = token.accessToken;
    session.user.apiToken = token.apiToken;
    return session;
  },
}

2.4 Token Usage in GraphQL

When making authenticated requests (e.g., adding to cart, viewing orders), the accessToken is retrieved from the NextAuth session and injected into the GraphQL headers via the Apollo Link.

📖 See: Apollo Client Setup

2.5 Security Best Practices

IMPORTANT

NEXTAUTH_SECRET: This environment variable is critical for encrypting the session JWT. Ensure it is a long, random string generated via openssl rand -base64 32.

  • Client-Side: Use the useSession() hook to check authentication status.
  • Server-Side: Use getServerSession(authOptions) for secure server-side checks.
  • Token Storage: Authentication tokens are stored in an encrypted HTTP-only cookie by NextAuth for maximum security.

2.6 Common Workflows

Manual Sign-In

typescript
import { signIn } from "next-auth/react";

const handleLogin = async (data) => {
  await signIn("credentials", {
    username: data.email,
    password: data.password,
    callbackUrl: "/customer/account",
  });
};

Checking Auth in Middleware

To protect entire routes, use Next.js Middleware in conjunction with NextAuth.

🏗️ Next Steps:

Released under the MIT License.