-
-
Notifications
You must be signed in to change notification settings - Fork 4k
Description
What Medusa version and documentation are you using?
None
Preliminary Checks
- This issue is not a duplicate. Before opening a new issue, please search existing issues: https://github.com/medusajs/medusa/issues
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:
- Token Inaccessibility: The client-side SDK cannot access the HttpOnly cookie.
- 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. - 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