Skip to Content
GuidesSoftware DeveloperAuthentication (Next.js)

Authentication with Next.js and Geobase

In this guide, we’ll walk you through implementing a modern authentication blueprint using Next.js 14 and Geobase, featuring server-side session management, protected routes, and secure middleware handling.

geobase-auth-flow

What’s Included

This authentication blueprint provides:

  • 🔐 Server-side and client-side auth utilities
  • 🚀 Middleware session management
  • 🛡️ Protected route handling
  • 🍪 Secure cookie management
  • 📱 SSR-compatible authentication
ℹ️

This implementation uses geobase’s SSR-compatible authentication helpers for optimal security and performance.

GitHub Repository

You can find the complete source code for this authentication system in the following GitHub repository:

Authentication Patterns

Geobase Auth can be implemented in several ways:

  1. Server-Side Authentication (Recommended)

    • Tokens stored in cookies
    • Protected API routes
    • Server-side session verification
  2. Client-Side Authentication

    • Browser-based token storage
    • Real-time subscription support
    • Instant UI updates
ℹ️

Server-side auth is recommended for better security and SEO optimization.

Implementation

Client Setup

Create a browser client for client-side authentication:

// utils/geobase/client.ts import { createBrowserClient } from '@supabase/ssr' export function createClient() { return createBrowserClient( process.env.NEXT_PUBLIC_GEOBASE_URL!, process.env.NEXT_PUBLIC_GEOBASE_ANON_KEY! ) }

Server Setup

Set up server-side authentication handling:

// utils/geobase/server.ts import { createServerClient } from '@supabase/ssr' import { cookies } from 'next/headers' export function createClient() { const cookieStore = cookies() return createServerClient( process.env.NEXT_PUBLIC_GEOBASE_URL!, process.env.NEXT_PUBLIC_GEOBASE_ANON_KEY!, { cookies: { get(name) { return cookieStore.get(name)?.value }, set(name, value, options) { try { cookieStore.set(name, value, options) } catch { // Cookie setting in Server Components can be ignored if middleware handles session refresh } }, remove(name, options) { try { cookieStore.set(name, '', { ...options, maxAge: 0 }) } catch { // Cookie removal in Server Components can be ignored if middleware handles session refresh } } } } ) }

Middleware Configuration

Create a middleware handler to protect routes and manage sessions:

// middleware.ts import { type NextRequest } from 'next/server' import { updateSession } from '@/utils/geobase/middleware' export async function middleware(request: NextRequest) { return await updateSession(request) } export const config = { matcher: [ '/((?!_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)', ], }
⚠️

The middleware matcher pattern excludes static files and images while protecting all other routes. Adjust the pattern based on your needs.

Session Management

Implement session updates in the middleware:

// utils/geobase/middleware.ts import { createServerClient } from '@supabase/ssr' import { NextResponse, type NextRequest } from 'next/server' export async function updateSession(request: NextRequest) { let response = NextResponse.next({ request: { headers: request.headers, }, }) const geobase = createServerClient( process.env.NEXT_PUBLIC_GEOBASE_URL!, process.env.NEXT_PUBLIC_GEOBASE_ANON_KEY!, { cookies: { get(name) { return request.cookies.get(name)?.value }, set(name, value, options) { request.cookies.set({ name, value, ...options, }) response = NextResponse.next({ request: { headers: request.headers, }, }) response.cookies.set({ name, value, ...options, }) }, remove(name, options) { request.cookies.set({ name, value: '', ...options, }) response = NextResponse.next({ request: { headers: request.headers, }, }) response.cookies.set({ name, value: '', ...options, }) }, }, } ) const { data: { user } } = await geobase.auth.getUser() if (!user && !request.nextUrl.pathname.startsWith('/login')) { const url = request.nextUrl.clone() url.pathname = '/login' return NextResponse.redirect(url) } return response }
ℹ️

Avoid adding logic between createServerClient and geobase.auth.getUser() to prevent unexpected session termination.

Environment Setup

To connect your app to Geobase, configure these environment variables. Include them in a .env.local file for local development.

NEXT_PUBLIC_GEOBASE_URL=https://YOUR_PROJECT_REF.geobase.app NEXT_PUBLIC_GEOBASE_ANON_KEY=YOUR_GEOBASE_PROJECT_ANON_KEY

You can locate the project reference and anon key in your Geobase project settings.

Shareable Maps

Local Development

  • Set Node.js version: Use Node version 21:
    nvm use 21
  • Install dependencies: Use your preferred package manager:
    npm install # or yarn # or pnpm install
  • Start the development server with HTTPS enabled:
    npm run dev -- --experimental-https # or yarn dev --experimental-https # or pnpm dev --experimental-https
ℹ️

Note: Without --experimental-https, the email verification links might redirect to https://localhost:3000/..., causing errors. You can navigate manually by removing https from the URL if needed.

Access the project at https://localhost:3000.

Best Practices

  1. Cookie Management

    • Always return the middleware response object as is
    • Maintain cookie synchronization between browser and server
    • Handle cookie operations carefully in Server Components
  2. Session Handling

    • Implement proper error handling for auth operations
    • Use try-catch blocks for cookie operations
    • Consider middleware refresh patterns for Server Components
  3. Security

    • Protect sensitive routes using middleware
    • Implement proper redirect handling
    • Maintain secure cookie handling practices

geobase-auth-flow

Learn More

ℹ️

For support and questions, join the Geobase discord community .

Last updated on