0.1.14 • Published 2 months ago
@supercortex/react-auth v0.1.14
@supercortex/react-auth
React authentication client for SuperCortex applications with full server-side rendering support.
Features
- 🔐 Server-Side Authentication - Full SSR support with JWT validation
- 🍪 Secure Cookies - HTTP-only cookies for token storage
- 🔑 JWKS Support - Automatic key fetching and validation
- 🛡️ Middleware Protection - Route-level authentication
- ⚡ Zero Backend Dependency - Works without Python backend
- 🎯 TypeScript - Full type safety
- 🔄 Auto Refresh - Automatic token refresh handling
Installation
npm install @supercortex/react-auth
Quick Start
1. Environment Variables
# .env.local
NEXT_PUBLIC_AUTH_SERVICE_URL=https://auth.apps.yourdomain.com
AUTH_COOKIE_NAME=auth_token
AUTH_ENABLED=true
2. Middleware Setup
Create middleware.ts
in your project root:
import { createAuthMiddleware } from '@supercortex/react-auth/server'
export const middleware = createAuthMiddleware({
publicPaths: ['/api/health', '/about', '/login']
})
export const config = {
matcher: ['/((?!_next/static|_next/image|favicon.ico).*)']
}
3. Server Components
// app/dashboard/page.tsx
import { requireAuth, getUser } from '@supercortex/react-auth/server'
// Protected page - redirects if not authenticated
export default async function DashboardPage() {
const user = await requireAuth()
return (
<div>
<h1>Welcome, {user.email}!</h1>
</div>
)
}
// Optional auth page
export default async function PublicPage() {
const user = await getUser()
return (
<div>
{user ? (
<h1>Hello, {user.email}</h1>
) : (
<h1>Hello, anonymous user</h1>
)}
</div>
)
}
4. API Routes
// app/api/protected/route.ts
import { withAuth } from '@supercortex/react-auth/server'
export const GET = withAuth(async (request, user) => {
return Response.json({
message: `Hello ${user.email}`,
userId: user.sub
})
})
// app/api/public/route.ts
import { withOptionalAuth } from '@supercortex/react-auth/server'
export const GET = withOptionalAuth(async (request, user) => {
if (user) {
return Response.json({ message: `Hello ${user.email}` })
}
return Response.json({ message: 'Hello anonymous user' })
})
5. Client Components (Optional)
For client-side auth state management:
// app/layout.tsx
import { ClientAuthProvider } from '@supercortex/react-auth'
export default function RootLayout({ children }) {
return (
<html>
<body>
<ClientAuthProvider>
{children}
</ClientAuthProvider>
</body>
</html>
)
}
// components/UserProfile.tsx
'use client'
import { useClientAuth } from '@supercortex/react-auth'
export function UserProfile() {
const { user, isLoading, login, logout } = useClientAuth()
if (isLoading) return <div>Loading...</div>
if (!user) return <button onClick={login}>Login</button>
return (
<div>
<span>Welcome, {user.email}</span>
<button onClick={logout}>Logout</button>
</div>
)
}
Advanced Usage
Custom Middleware Configuration
import { createAuthMiddleware } from '@supercortex/react-auth/server'
export const middleware = createAuthMiddleware({
authUrl: 'https://custom-auth.example.com',
cookieName: 'custom_token',
publicPaths: ['/api/health', '/about', '/pricing'],
authEnabled: process.env.NODE_ENV !== 'development'
})
Backend Compatibility Routes
Add these routes for FastAPI backend compatibility:
// app/api/v1/auth-url/route.ts
export { GET } from '@supercortex/react-auth/server'
// app/api/v1/user/route.ts
export { getUserHandler as GET } from '@supercortex/react-auth/server'
Error Handling
// app/error.tsx
'use client'
export default function Error({ error, reset }) {
if (error.message === 'Authentication required') {
return (
<div>
<h2>Please log in to continue</h2>
<button onClick={() => window.location.href = '/login'}>
Go to Login
</button>
</div>
)
}
return (
<div>
<h2>Something went wrong!</h2>
<button onClick={reset}>Try again</button>
</div>
)
}
Configuration Options
Option | Type | Default | Description |
---|---|---|---|
authUrl | string | process.env.NEXT_PUBLIC_AUTH_SERVICE_URL | Auth service URL |
jwksUrl | string | ${authUrl}/api/v1/auth/.well-known/jwks.json | JWKS endpoint |
cookieName | string | auth_token | Cookie name for JWT token |
publicPaths | string[] | ['/api/health', '/health', '/_next', '/favicon.ico'] | Paths that skip auth |
algorithm | string | RS256 | JWT algorithm |
authEnabled | boolean | true | Enable/disable auth |
Security Features
- ✅ HTTP-only Cookies - Prevents XSS attacks
- ✅ JWKS Validation - Cryptographic signature verification
- ✅ Token Expiration - Automatic expiry handling
- ✅ Secure Headers - Proper cookie security attributes
- ✅ CSRF Protection - SameSite cookie attributes
Architecture
This library provides server-side authentication that works independently of any backend service. It validates JWT tokens using JWKS from your auth service and can protect routes at the middleware level.
Flow:
- User visits protected route
- Middleware checks for valid JWT cookie
- If valid, user data is attached to request headers
- Server components can access user data
- If invalid, user is redirected to auth service
Migration from Client-Only Auth
If you're currently using client-only auth, you can gradually migrate:
- Add middleware for route protection
- Update server components to use
getUser()
/requireAuth()
- Keep existing client components unchanged
- Optionally remove client auth provider if not needed
License
MIT