Examples
Practical examples for common authentication scenarios.
Protected API Route
Secure your API endpoints.
// Next.js API Route
import { getSession } from '@optare/nextjs'
export async function GET(request: Request) {
const session = await getSession()
if (!session) {
return new Response('Unauthorized', { status: 401 })
}
const data = await fetchUserData(session.user.id)
return Response.json(data)
}Organization Check
Verify user belongs to an organization.
async function requireOrganization(userId: string, orgId: string) {
const membership = await authClient.organization.getMembership({
userId,
organizationId: orgId
})
if (!membership) {
throw new Error('Not a member of this organization')
}
return membership
}Role-Based UI
Show/hide UI based on user role.
function AdminPanel() {
const { user } = useAuth()
if (!['owner', 'admin'].includes(user.role)) {
return null
}
return (
<div>
<h2>Admin Panel</h2>
{/* Admin-only content */}
</div>
)
}Custom Login Page
Build a custom login form.
import { useState } from 'react'
import { authClient } from '@optare/client'
function LoginForm() {
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const [error, setError] = useState('')
async function handleSubmit(e) {
e.preventDefault()
try {
await authClient.signIn.email({ email, password })
window.location.href = '/dashboard'
} catch (err) {
setError('Invalid credentials')
}
}
return (
<form onSubmit={handleSubmit}>
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="Email"
/>
<input
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
placeholder="Password"
/>
{error && <p>{error}</p>}
<button type="submit">Sign In</button>
</form>
)
}Session Refresh
Keep sessions alive automatically.
import { useEffect } from 'react'
import { authClient } from '@optare/client'
function useSessionRefresh() {
useEffect(() => {
const interval = setInterval(async () => {
try {
await authClient.refreshSession()
} catch (err) {
// Session expired, redirect to login
window.location.href = '/login'
}
}, 15 * 60 * 1000) // Every 15 minutes
return () => clearInterval(interval)
}, [])
}Multi-Tenant Routing
Route users based on organization.
// middleware.ts
import { getSession } from '@optare/nextjs'
import { NextResponse } from 'next/server'
export async function middleware(request) {
const session = await getSession()
if (!session) {
return NextResponse.redirect('/login')
}
const org = session.user.organization
const subdomain = request.headers.get('host').split('.')[0]
if (org.slug !== subdomain) {
return NextResponse.redirect(`https://${org.slug}.yourapp.com`)
}
return NextResponse.next()
}Webhook Handler
Process authentication events.
import { verifyWebhook } from '@optare/webhooks'
export async function POST(request: Request) {
const signature = request.headers.get('x-optare-signature')
const body = await request.text()
if (!verifyWebhook(body, signature, process.env.WEBHOOK_SECRET)) {
return new Response('Invalid signature', { status: 401 })
}
const event = JSON.parse(body)
switch (event.type) {
case 'user.created':
await onUserCreated(event.data)
break
case 'user.deleted':
await onUserDeleted(event.data)
break
}
return new Response('OK')
}Next Steps
- Quick Start - Get started guide
- API Reference - Complete API docs
- Integrations - Framework guides