Deployment
Examples

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