NextAuth.js Hasura Adapter
The `next-auth-hasura-adapter` is a specialized adapter designed to integrate NextAuth.js authentication with a Hasura GraphQL engine backend. It is currently at version 2.0.0 and functions as a peer dependency of `next-auth` (specifically compatible with `next-auth` v4.x and above), meaning its release cycle is inherently tied to the evolution of the core NextAuth.js library. This package facilitates the storage and retrieval of authentication-related data, such as users, accounts, sessions, and verification tokens, directly within a PostgreSQL database managed by Hasura. It distinguishes itself by providing a `HasuraAdapter` instance that connects to a Hasura endpoint via GraphQL, eliminating the need for separate ORM configurations or database setups for NextAuth's internal data. Developers must apply a provided SQL schema to their Hasura-connected database to ensure the necessary tables and relationships are present for the adapter to function correctly. This makes it an ideal choice for projects already leveraging Hasura as their backend.
Common errors
-
Error: "The next-auth-hasura-adapter requires the 'endpoint' and 'admin_secret' options to be set."
cause The `endpoint` or `admin_secret` properties were not provided or were empty strings in the HasuraAdapter configuration.fixEnsure `endpoint` and `admin_secret` are correctly supplied to the `HasuraAdapter` function, typically through environment variables like `process.env.HASURA_GRAPHQL_ENDPOINT` and `process.env.HASURA_GRAPHQL_ADMIN_SECRET`. -
GraphQL Error: "column \"userId\" of relation \"accounts\" does not exist" or similar 'table/column not found' errors.
cause The required NextAuth database schema has not been correctly applied to your Hasura-managed PostgreSQL database.fixExecute the SQL script `src/data/nextauth.sql` (or the one provided in the README) against your PostgreSQL database to create all necessary tables and relationships (e.g., `accounts`, `sessions`, `users`, `verification_tokens`). -
NextAuth.js: No adapter has been specified
cause The `adapter` property is missing or incorrectly configured within your `NextAuth` configuration object.fixAdd the `adapter: HasuraAdapter(...)` configuration to your `NextAuth` options in `pages/api/auth/[...nextauth].ts` or equivalent API route. -
TypeError: HasuraAdapter is not a function
cause The `HasuraAdapter` was imported incorrectly, or the `next-auth-hasura-adapter` package might not be installed correctly.fixEnsure you are using `import { HasuraAdapter } from 'next-auth-hasura-adapter';` and that the package is properly installed via `npm install next-auth-hasura-adapter`.
Warnings
- breaking This adapter is built specifically for NextAuth.js v4.x and higher. It is not compatible with NextAuth.js v3.x or earlier versions, which had significant API changes.
- gotcha The adapter requires a specific SQL schema to be applied to your Hasura-connected PostgreSQL database. Failure to apply the `nextauth.sql` schema will result in runtime errors when the adapter attempts to interact with non-existent tables or columns.
- gotcha The `admin_secret` for your Hasura instance should *never* be exposed client-side. Always pass it via secure server-side environment variables.
- gotcha The `endpoint` option must point to your Hasura GraphQL API endpoint (e.g., `https://my-hasura-app.com/v1/graphql`), not the Hasura Console URL or any other administrative endpoint.
- gotcha A `secret` property is required in the `NextAuth` configuration object when deploying to production, even when using an adapter, for JWT signing and encryption.
Install
-
npm install next-auth-hasura-adapter -
yarn add next-auth-hasura-adapter -
pnpm add next-auth-hasura-adapter
Imports
- HasuraAdapter
const HasuraAdapter = require('next-auth-hasura-adapter');import { HasuraAdapter } from 'next-auth-hasura-adapter'; - HasuraAdapterOptions
import type { HasuraAdapterOptions } from 'next-auth-hasura-adapter'; - NextAuth
import { NextAuth } from 'next-auth';import NextAuth from 'next-auth';
Quickstart
// pages/api/auth/[...nextauth].ts
import NextAuth from "next-auth";
import GitHubProvider from "next-auth/providers/github"; // Example provider
import { HasuraAdapter } from "next-auth-hasura-adapter";
// Ensure your Hasura GraphQL endpoint and admin secret are set as environment variables.
// Example: HASURA_GRAPHQL_ENDPOINT=https://your-hasura-instance/v1/graphql
// Example: HASURA_GRAPHQL_ADMIN_SECRET=your_admin_secret_here
const HASURA_API_ENDPOINT = process.env.HASURA_GRAPHQL_ENDPOINT ?? '';
const HASURA_ADMIN_SECRET = process.env.HASURA_GRAPHQL_ADMIN_SECRET ?? '';
if (!HASURA_API_ENDPOINT || !HASURA_ADMIN_SECRET) {
throw new Error("Missing Hasura GraphQL Endpoint or Admin Secret environment variables. Please set HASURA_GRAPHQL_ENDPOINT and HASURA_GRAPHQL_ADMIN_SECRET.");
}
export default NextAuth({
// Configure one or more authentication providers (e.g., GitHub)
providers: [
GitHubProvider({
clientId: process.env.GITHUB_ID ?? '', // Ensure GITHUB_ID is set in your .env
clientSecret: process.env.GITHUB_SECRET ?? '', // Ensure GITHUB_SECRET is set in your .env
}),
// Add more providers as needed (e.g., GoogleProvider, EmailProvider)
],
// Use the Hasura Adapter to persist user data
adapter: HasuraAdapter({
endpoint: HASURA_API_ENDPOINT,
admin_secret: HASURA_ADMIN_SECRET,
}),
// Recommended for adapters like Hasura for stateless sessions
session: {
strategy: "jwt"
},
// Define callbacks to customize JWT and session objects
callbacks: {
async jwt({ token, user }) {
if (user) {
token.id = user.id; // Attach user ID to the JWT
}
// Custom Hasura claims can be added here if needed for authorization
return token;
},
async session({ session, token }) {
// Expose user ID to the client via the session object
if (session.user) {
session.user.id = token.id;
}
return session;
},
},
// NEXTAUTH_SECRET is required for any NextAuth.js application in production
secret: process.env.NEXTAUTH_SECRET ?? ''
});