Skip to content

auth() Returns Null in App Router Despite Valid Session Cookie and Database Session (#12848 Follow-Up) #12894

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

Open
lwensveen opened this issue Apr 22, 2025 · 3 comments
Labels
bug Something isn't working triage Unseen or unconfirmed by a maintainer yet. Provide extra information in the meantime.

Comments

@lwensveen
Copy link

Environment

  System:
    OS: macOS 15.4.1
    CPU: (8) arm64 Apple M1
    Memory: 101.52 MB / 8.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 20.19.0 - /opt/homebrew/opt/node@20/bin/node
    npm: 10.8.2 - /opt/homebrew/opt/node@20/bin/npm
    pnpm: 10.6.5 - ~/Library/pnpm/pnpm
    bun: 1.2.10 - /opt/homebrew/bin/bun
  Browsers:
    Brave Browser: 135.1.77.97
    Chrome: 135.0.7049.96
    Safari: 18.4
  npmPackages:
    @auth/drizzle-adapter: ^1.9.0 => 1.9.0
    @auth/unstorage-adapter: ^2.0.0 => 2.8.0
    next: latest => 15.3.1
    next-auth: beta => 5.0.0-beta.26
    react: ^18.2.0 => 18.3.1

Reproduction URL

https://github.com/lwensveen/next-auth-example/tree/drizzle-credentials-session-issue

Describe the issue

In NextAuth v5 ([email protected], @auth/[email protected]), auth() returns null in Server Components and server-side contexts (e.g., API fetches) in the App Router, despite a valid authjs.session-token cookie and a corresponding session in the database (sessionTable). This causes No active session errors and redirect loops to the sign-in page, breaking protected routes. The issue is a follow-up to discussion #12848, which describes similar session handling problems with the Drizzle adapter.

I’ve created a minimal reproduction in lwensveen/next-auth-example, showing that after a successful login via the Credentials provider, auth() fails to recognize the session, even though the cookie is set and the session exists in the database. Manual session creation in the jwt callback (as a workaround) creates a session, but auth() still returns null, suggesting a bug in the Drizzle adapter or App Router session retrieval.

How to reproduce

# Install Dependencies
npm install

# Set Up PostgreSQL
# Install PostgreSQL or use a service (e.g., Neon, Supabase).
# Create a database named next_auth_example:
psql -U postgres
CREATE DATABASE next_auth_example;

# Update .env.local with:
# .env.local
DATABASE_URL=postgres://postgres:password@localhost:5432/next_auth_example
AUTH_SECRET=your-secure-secret-here
NEXT_PUBLIC_API_URL=http://localhost:3000

# Generate AUTH_SECRET:
openssl rand -base64 32

# Run Migrations:
npx drizzle-kit generate
npx drizzle-kit migrate

# Create a Test User
# Generate a bcrypt hash for password123:
node -e "require('bcrypt').hash('password123', 10, (err, hash) => console.log(hash))"

# Insert user:
psql -U postgres -d next_auth_example
INSERT INTO users (id, email, password_hash, created_at) VALUES (
  gen_random_uuid(),
  '[email protected]',
  '$2b$10$your_hashed_password',
  NOW()
);

# Start the App:
npm run dev

# Reproduce the Issue:
# 1. Visit http://localhost:3000/auth/signin.
# 2. Log in with email: [email protected], password: password123.
# 3. Verify the authjs.session-token cookie is set (browser dev tools: Application > Cookies).
# 4. Navigate to http://localhost:3000/protected.
# 5. Observe:
#    - Redirect to /auth/signin (307) or No active session error.
#    - Console logs show session: null for ProtectedPage session:, fetchData session:, or Middleware session:.
# 6. Check the database:
psql -U postgres -d next_auth_example -c "SELECT * FROM session"
#    - A session exists with sessionToken, userId, and expires.

# Expected Behavior
# - After login, the authjs.session-token cookie is set, and a session is created in sessionTable.
# - Navigating to /protected loads the page with session data and fetched data (e.g., /api/data).
# - auth() returns a valid session in Server Components and server-side fetches, using the cookie to retrieve the session from sessionTable.

# Actual Behavior
# - Login succeeds (/api/auth/callback/credentials returns 200), and the authjs.session-token cookie is set.
# - A session is created in sessionTable (via manual jwt callback workaround).
# - Navigating to /protected triggers a 307 redirect to /auth/signin, or fetchData throws No active session.
# - Console logs show session: null for ProtectedPage session:, fetchData session:, and Middleware session:.
# - SELECT * FROM session confirms a valid session exists, but auth() fails to retrieve it.

# Logs
# Console Logs (example):
Authorized user: {
  id: 'b3ada650-3833-4d6c-a27f-a8242d031658',
  email: '[email protected]',
  name: null,
  image: null,
  emailVerified: null,
  createdAt: '2025-04-22T09:26:26.126Z',
  updatedAt: '2025-04-22T09:26:26.126Z'
}
jwt callback - token: {
  name: null,
  email: '[email protected],
  picture: null,
  sub: 'b3ada650-3833-4d6c-a27f-a8242d031658'
} user: {
  id: 'b3ada650-3833-4d6c-a27f-a8242d031658',
  email: '[email protected],
  name: null,
  image: null,
  emailVerified: null,
  createdAt: '2025-04-22T09:26:26.126Z',
  updatedAt: '2025-04-22T09:26:26.126Z'
} account: {
  providerAccountId: 'b3ada650-3833-4d6c-a27f-a8242d031658',
  type: 'credentials',
  provider: 'credentials'
} trigger: signIn session: undefined
No session found for user b3ada650-3833-4d6c-a27f-a8242d031658
ProtectedPage session: null
fetchData session: null
Middleware session: null
Fetched /api/data: Error: No active session

# Database:
SELECT * FROM session;
 sessionToken | userId | expires
-------------+--------+---------
 <token>     | b3ada650-3833-4d6c-a27f-a8242d031658 | 2025-05-22T09:26:26.126Z

# Cookie:
# - Name: authjs.session-token
# - Value: <valid-token>
# - Attributes: HttpOnly; SameSite=Lax; Path=/; Secure=false

### Expected behavior

It should log in with a valid session.
@lwensveen lwensveen added bug Something isn't working triage Unseen or unconfirmed by a maintainer yet. Provide extra information in the meantime. labels Apr 22, 2025
@VitoorVictor
Copy link

I have the same error, did you manage to solve it? I am authenticating with Credentials, it goes through my auth, there is a return from the API, and my Jwt CallBack works, but the session is always null,

@lwensveen
Copy link
Author

I have the same error, did you manage to solve it? I am authenticating with Credentials, it goes through my auth, there is a return from the API, and my Jwt CallBack works, but the session is always null,

Never solved it, migrated to better auth and that works perfectly.

@VitoorVictor
Copy link

I have the same error, did you manage to solve it? I am authenticating with Credentials, it goes through my auth, there is a return from the API, and my Jwt CallBack works, but the session is always null,

Never solved it, migrated to better auth and that works perfectly.

He bro, I solved it, in my project there were conflicting environment variables.

My .env before revolser

AUTH_SECRET=secret here
API_LOGIN_URL=https://localhost:8080/sign-in
NEXT_PUBLIC_API_URL=https://localhost:8080
NEXT_API_URL=https://localhost:8080

My .env after revolser

AUTH_SECRET=secret here
API_LOGIN_URL=https://localhost:8080/sign-in
NEXT_PUBLIC_API_URL=https://localhost:8080
NEXT_API_URL=https://localhost:8080
NEXTAUTH_URL=http://localhost:3000

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working triage Unseen or unconfirmed by a maintainer yet. Provide extra information in the meantime.
Projects
None yet
Development

No branches or pull requests

2 participants