WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Docs Rewrite Proposal: Third-Party Login with Next.js Server Actions & HttpOnly Cookies #14251

@mocker12345

Description

@mocker12345

What Medusa version and documentation are you using?

None

Preliminary Checks

Issue Summary

Problem Description

The current Third-Party Login Guide primarily describes a Client-Side Flow, where the JS SDK is expected to manage the token in client-side storage (e.g., localStorage).

However, in modern Next.js App Router architectures (like the official starter), we often rely on HttpOnly Cookies for security. In this "Server-Side Only" setup:

  1. Token Inaccessibility: The client-side SDK cannot access the HttpOnly cookie.
  2. Context Disconnect: When using Server Actions, the sdk.auth.refresh() call defaults to looking for cookies in the incoming request. During the initial callback (creation) phase, the new auth state hasn't been written to the client's cookies yet.
  3. Result: Developers following the docs end up with a broken flow or have to force a "Double Login" (User logs in -> Account Created -> User must log in again to get the cookie).

Proposed Solution: Single-Step Server-Side Flow

We successfully implemented a seamless flow by handling the refresh entirely on the server within the callback Server Action.

The key is explicitly passing the initialToken (Identity Token) to sdk.auth.refresh via headers, bypassing the need for browser-to-server cookie roundtrips.

Implementation Pattern

In your validateCallback Server Action:

// src/lib/data/customer.ts (Server Action)
import { sdk } from "@lib/config"

export async function validateGoogleCallback(queryParams) {
  // 1. Get Identity Token from Provider
  const initialToken = await sdk.auth.callback("customer", "google", queryParams)

  // 2. Check if this is a New User (simplified logic)
  const decoded = decodeToken(initialToken)
  const isNewUser = !decoded?.actor_id

  if (isNewUser) {
    // 3. Create Customer
    await sdk.store.customer.create({ 
      email: decoded.email, 
      // ... 
    }, {}, { Authorization: `Bearer ${initialToken}` })

    // 4. CRITICAL STEP: Immediate Server-Side Refresh
    // We manually pass the initialToken in headers because cookies aren't set yet.
    // This exchanges the Identity Token for a full Customer Token.
    const refreshedToken = await sdk.auth.refresh({
      Authorization: `Bearer ${initialToken}`
    })

    // 5. Set the valid cookie (HttpOnly) server-side
    await setAuthToken(refreshedToken)
    
    return { success: true } 
  }
  
  // Existing user logic...
}

Recommendation

Please consider adding a section or a "Recipe" for Next.js Server Actions.

Why: This is a critical pattern for secure enterprise implementations using Medusa + Next.js, as it avoids exposing tokens to localStorage while maintaining a frictionless UX (no double login).

How can this issue be resolved?

No response

Are you interested in working on this issue?

  • I would like to fix this issue

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions