JSTAcademy
0 XP
Dashboard
Crash Courses
Authentication in APIs
11 min
Basic+150 XP
Crash Courses · Basic

Authentication in APIs

Secure REST endpoints with JWT tokens and API key authentication.
11 min read+150 XP on completionCert: REST APIs Crash Course
Tap any word in the text below to start reading from there.

Authentication in APIs

REST APIs are stateless authentication tokens must be sent with every request in headers.

JWT Auth Pattern

// Middleware auth check
import { createServerClient } from '@supabase/ssr'
import { NextRequest, NextResponse } from 'next/server'

async function getAuthUser(req: NextRequest) {
  const authHeader = req.headers.get('Authorization')
  if (!authHeader?.startsWith('Bearer ')) return null

  const token = authHeader.slice(7)
  const supabase = createClient()
  const { data: { user } } = await supabase.auth.getUser(token)
  return user
}

// Protected route
export async function GET(req: NextRequest) {
  const user = await getAuthUser(req)
  if (!user) {
    return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
  }

  const progress = await getProgress(user.id)
  return NextResponse.json({ data: progress })
}

Sending Auth from the Client

'use client'
import { createClient } from '@/lib/supabase/client'

async function fetchMyProgress() {
  const supabase = createClient()
  const { data: { session } } = await supabase.auth.getSession()

  const res = await fetch('/api/progress', {
    headers: {
      Authorization: `Bearer ${session?.access_token}`,
      'Content-Type': 'application/json',
    },
  })

  return res.json()
}

API Key Auth (Server-to-Server)

// Route Handler
export async function POST(req: NextRequest) {
  const apiKey = req.headers.get('X-API-Key')

  if (apiKey !== process.env.INTERNAL_API_KEY) {
    return NextResponse.json({ error: 'Forbidden' }, { status: 403 })
  }

  // process request...
}

// Calling from another service
await fetch('/api/internal/sync', {
  method: 'POST',
  headers: {
    'X-API-Key': process.env.INTERNAL_API_KEY!,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify(payload),
})
0%