npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@gittielabs/nextjs-fastapi-auth

v0.1.0

Published

Next.js authentication utilities for FastAPI backend

Downloads

5

Readme

@gittielabs/nextjs-fastapi-auth

Authentication and authorization library for Next.js 15+ applications with Supabase backend integration.

Installation

npm install @gittielabs/nextjs-fastapi-auth
# or
yarn add @gittielabs/nextjs-fastapi-auth
# or
pnpm add @gittielabs/nextjs-fastapi-auth

Features

  • 🔐 JWT Token Management - Extract and validate Supabase JWT tokens
  • 🛡️ Admin Authentication - Server-side admin role verification
  • 🔄 Auth Middleware - Automatic authentication and subdomain handling
  • 🌐 Multi-Tenancy - Organization context via subdomains
  • 📡 WebSocket Support - Authenticated WebSocket connections
  • 🚀 Next.js 15 Compatible - Full support for async cookies and headers

Quick Start

1. Environment Setup

Create a .env.local file:

NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key

2. Middleware Setup

Create or update middleware.ts:

import { authMiddleware } from '@gittielabs/nextjs-fastapi-auth/middleware'

export default authMiddleware

export const config = {
  matcher: [
    '/((?!_next/static|_next/image|favicon.ico|public/).*)',
  ],
}

3. Protected API Routes

Use admin authentication in API routes:

// app/api/admin/users/route.ts
import { validateAdminAuth } from '@gittielabs/nextjs-fastapi-auth/server'
import { NextRequest, NextResponse } from 'next/server'

export async function GET(request: NextRequest) {
  const auth = validateAdminAuth(request)

  if (auth.error) {
    return auth.error
  }

  // User is authenticated as admin
  return NextResponse.json({
    user: auth.user,
    message: 'Admin access granted'
  })
}

4. Client-Side Authentication

Use authenticated fetch for API calls:

'use client'

import { authenticatedFetch } from '@gittielabs/nextjs-fastapi-auth/client'

export default function MyComponent() {
  const fetchData = async () => {
    const response = await authenticatedFetch('/api/data')
    const data = await response.json()
    console.log(data)
  }

  return <button onClick={fetchData}>Fetch Data</button>
}

Core Components

JWT Utilities

Extract and decode JWT tokens:

import {
  extractJwtFromRequest,
  extractJwtPayload,
  extractSubdomainFromJwt
} from '@gittielabs/nextjs-fastapi-auth/jwt'

// Extract JWT from NextRequest
const token = extractJwtFromRequest(request)

// Decode JWT payload
const payload = extractJwtPayload(token)
if (payload) {
  console.log('User ID:', payload.sub)
  console.log('Email:', payload.email)
}

// Extract organization subdomain
const subdomain = extractSubdomainFromJwt(token)

Admin Authentication

Validate admin access in API routes:

import { validateAdminAuth } from '@gittielabs/nextjs-fastapi-auth/server'

export async function POST(request: NextRequest) {
  const auth = validateAdminAuth(request)

  if (auth.error) {
    return auth.error // Returns 401 or 403 response
  }

  // Access authenticated user data
  const { user } = auth
  console.log('Admin user:', user.email)
  console.log('Organization:', user.organization_subdomain)

  // Proceed with admin operation...
}

Middleware

The auth middleware handles:

  • Authentication verification
  • Subdomain-based routing
  • WWW redirect
  • Protected route enforcement
import { authMiddleware } from '@gittielabs/nextjs-fastapi-auth/middleware'

// Use as-is or customize configuration
export default authMiddleware

// Or create custom middleware
import { NextRequest, NextResponse } from 'next/server'
import { extractJwtFromRequest } from '@gittielabs/nextjs-fastapi-auth/jwt'

export async function middleware(request: NextRequest) {
  const token = extractJwtFromRequest(request)

  if (!token && request.nextUrl.pathname.startsWith('/protected')) {
    return NextResponse.redirect(new URL('/login', request.url))
  }

  return NextResponse.next()
}

Authenticated Fetch

Client-side fetch with automatic authentication:

import { authenticatedFetch } from '@gittielabs/nextjs-fastapi-auth/client'

// Automatically includes Authorization header
const response = await authenticatedFetch('/api/data', {
  method: 'POST',
  body: JSON.stringify({ key: 'value' }),
})

const data = await response.json()

WebSocket Support

Create authenticated WebSocket connections:

import { createAuthenticatedWebSocket } from '@gittielabs/nextjs-fastapi-auth/client'

const ws = await createAuthenticatedWebSocket('wss://api.example.com/ws')

ws.onmessage = (event) => {
  console.log('Message:', event.data)
}

ws.send(JSON.stringify({ action: 'subscribe', channel: 'updates' }))

User Roles and Permissions

The library supports role-based access control:

interface JwtPayload {
  sub: string                    // User ID
  email: string                  // User email
  user_metadata: {
    role?: string                // User role
    is_super_admin?: boolean     // Super admin flag
    organization_subdomain?: string
  }
  // ... other Supabase JWT fields
}

Roles are used by the admin authentication to control access:

  • Super admins have access to all organizations
  • Organization admins can access their organization's admin routes
  • Regular users are blocked from admin routes

API Reference

JWT Functions

extractJwtFromRequest(request: NextRequest): string | null

Extract JWT token from request headers or cookies.

extractJwtPayload(token: string): JwtPayload | null

Decode and parse JWT payload.

extractSubdomainFromJwt(token: string): string | null

Extract organization subdomain from JWT metadata.

extractSubdomainFromRequest(request: NextRequest): string | null

Extract subdomain from request hostname.

Server Functions

validateAdminAuth(request: NextRequest): { user: JwtPayload } | { error: NextResponse }

Validate that the request is from an authenticated admin user.

Returns either:

  • { user: JwtPayload } - User is authenticated as admin
  • { error: NextResponse } - Authentication failed (401 or 403)

Middleware

authMiddleware(request: NextRequest): Promise<NextResponse>

Complete authentication middleware with:

  • WWW redirect
  • Subdomain handling
  • Authentication verification
  • Protected route enforcement

Client Functions

authenticatedFetch(url: string, options?: RequestInit): Promise<Response>

Fetch with automatic JWT authentication.

createAuthenticatedWebSocket(url: string): Promise<WebSocket>

Create WebSocket connection with JWT authentication.

TypeScript Support

This library is written in TypeScript and includes full type definitions:

import type {
  JwtPayload,
  AdminAuthResult,
  AuthenticatedUser
} from '@gittielabs/nextjs-fastapi-auth'

Development

Running Tests

npm test

# With coverage
npm test -- --coverage

# Watch mode
npm test -- --watch

Building

npm run build

Linting

npm run lint

Best Practices

1. Server-Side Authentication

Always validate authentication on the server side:

// ✅ Good - Server-side validation
export async function GET(request: NextRequest) {
  const auth = validateAdminAuth(request)
  if (auth.error) return auth.error
  // ... secure operation
}

// ❌ Bad - Client-side only
'use client'
export default function AdminPanel() {
  // Client-side checks can be bypassed
}

2. Environment Variables

Keep sensitive keys secure:

// ✅ Good - Use environment variables
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL

// ❌ Bad - Hardcoded values
const supabaseUrl = 'https://myproject.supabase.co'

3. Error Handling

Handle authentication errors gracefully:

const auth = validateAdminAuth(request)

if (auth.error) {
  // Log error details server-side
  console.error('Auth failed:', auth.error)

  // Return user-friendly error
  return auth.error
}

4. Multi-Tenancy

Use subdomains for organization isolation:

// Extract subdomain for data filtering
const subdomain = extractSubdomainFromRequest(request)

// Filter queries by organization
const data = await db.query({
  where: { organization_subdomain: subdomain }
})

Troubleshooting

"No JWT token found"

Ensure the client is sending the Authorization header:

// Check if token exists in cookies
const cookies = await import('next/headers')
const cookieStore = await cookies.cookies()
const token = cookieStore.get('sb-access-token')

"Invalid JWT token"

Verify your Supabase configuration:

  • Check NEXT_PUBLIC_SUPABASE_URL is correct
  • Ensure SUPABASE_SERVICE_ROLE_KEY is the service role key (not anon key)
  • Confirm the JWT hasn't expired

"Subdomain not found"

Ensure your middleware is properly configured:

export const config = {
  matcher: [
    '/((?!_next/static|_next/image|favicon.ico).*)',
  ],
}

Migration Guide

From Previous Versions

If migrating from an older version:

  1. Update to Next.js 15+
  2. Make cookies and headers async:
// Before
const cookieStore = cookies()

// After (Next.js 15+)
const cookieStore = await cookies()
  1. Update middleware exports:
// Before
export { middleware } from '@gittielabs/nextjs-fastapi-auth'

// After
import { authMiddleware } from '@gittielabs/nextjs-fastapi-auth/middleware'
export default authMiddleware

Contributing

Contributions are welcome! Please see the main repository for guidelines.

License

MIT © GittieLabs

Support

For issues and questions: