ClientAuth
Session Management
How sessions, tokens, and automatic refresh work in the client SDK.
The auth client manages JWT sessions automatically — storing tokens, refreshing them before expiry, and clearing them on sign out.
import { useSession } from '@superapp/auth'
export function Dashboard() {
const { data: session, isPending } = useSession()
if (isPending) return <div>Loading...</div>
if (!session) return <div>Please sign in</div>
return <div>Welcome, {session.user.name}</div>
}How Sessions Work
- The user signs in through
AuthCardor the auth client API. - The server returns a JWT and a refresh token.
- The auth client stores the tokens and provides them via
useSession. - When you create a
dbclient withcreateDb(session.token), the JWT is sent with every query. - The server validates the JWT, extracts the user identity, and applies permissions.
Token Lifecycle
| Event | What Happens |
|---|---|
| Sign in | JWT + refresh token stored |
| Query | JWT sent in Authorization header |
| Token expiry approaching | Auth client refreshes automatically |
| Refresh token expired | Session cleared, user must sign in again |
| Sign out | Both tokens cleared |
Accessing the Session
In React Components
Use the useSession hook inside an AuthProvider.
import { useSession } from '@superapp/auth'
export function UserGreeting() {
const { data: session, isPending } = useSession()
if (isPending) return <span>Loading...</span>
if (!session) return <span>Guest</span>
return <span>Hello, {session.user.name}</span>
}For Database Queries
Use the useDb hook to get a typed client that is automatically null when no session exists.
import { useDb } from '@/hooks/use-db'
export function OrdersList() {
const db = useDb()
async function loadOrders() {
if (!db) return // Not authenticated
const orders = await db.main.orders.findMany({
select: ['id', 'amount', 'status'],
})
// orders: { id: string; amount: number; status: string }[]
}
}Reacting to Session Changes
Use the onSessionChange callback on AuthProvider to run side effects when the session changes (sign in, sign out, token refresh).
import { AuthProvider } from '@superapp/auth/components'
import { authClient } from '@/lib/superapp'
import { useRouter } from 'next/navigation'
export function Providers({ children }: { children: React.ReactNode }) {
const router = useRouter()
return (
<AuthProvider
authClient={authClient}
navigate={router.push}
replace={router.replace}
onSessionChange={() => router.refresh()}
>
{children}
</AuthProvider>
)
}Protected Routes
Check the session to gate access to authenticated pages.
import { useSession } from '@superapp/auth'
import { useRouter } from 'next/navigation'
import { useEffect } from 'react'
export function ProtectedPage({ children }: { children: React.ReactNode }) {
const { data: session, isPending } = useSession()
const router = useRouter()
useEffect(() => {
if (!isPending && !session) {
router.replace('/sign-in')
}
}, [session, isPending, router])
if (isPending) return <div>Loading...</div>
if (!session) return null
return <>{children}</>
}