Next.js Auth (Storefront)
Different from backend — client-side cookie + Zustand, middleware for route protection.
Token Storage
// js-cookie key "token", 90-day expiry
Cookies.set('token', accessToken, { expires: 90 });
useAuth Hook
const { login, register, loginWithGoogle, logout, user, isAuthenticated } = useAuth();
// login(credentials, redirectPath?) → set cookie → fetchProfile() → router.push
Files: hooks/useAuth.ts, stores/profile.store.ts, services/profile.service.ts
ProfileBootstrap
Client component returns null — fetches profile on mount (avoids cookies() in RSC header).
API Client Auto-Auth
// utils/api.ts — attaches Bearer from cookie on every request
const token = Cookies.get('token');
headers.Authorization = `Bearer ${token}`;
Middleware Protection
// middleware.ts
const token = request.cookies.get('token');
if (pathname.includes('/my-profile') && !token) {
return redirect(`/${locale}/sign-in?redirect=${encodeURIComponent(pathname)}`);
}
// Authenticated on /sign-in → redirect home
Protected: /my-profile, /orders. Legacy /my-orders → /my-profile?tab=orders.
Auth Pages
app/[locale]/(auth)/sign-in/page.tsx— client pagecomponents/auth/AuthForm.tsx— email/password (controlled state, not RHF)components/auth/GoogleAuthButton.tsx—NEXT_PUBLIC_GOOGLE_CLIENT_IDcomponents/auth/LoginModal.tsx— inline auth modal
API Endpoints
POST /auth/login, /auth/register, /auth/oauth/google
GET /auth/get-profile, /auth/logout
PATCH /auth/update-profile
Login Flow
- POST login → extract
accessTokenfrom response Cookies.set('token')fetchProfile()→ ZustanduseProfileStorerouter.push(redirect || '/')
Logout
Clear cookie + profile store + favorites → redirect sign-in.
Env
NEXT_PUBLIC_GOOGLE_CLIENT_ID, NEXT_PUBLIC_API_BASE_URL
Do not duplicate backend JWT/guard logic — frontend only stores token and attaches header.