---
title: "How to Implement Basic Authorization in Astro"
description: "Learn how to add basic authentication to your Astro application using middleware. Protect your routes before launching to production with this simple implementation."
source: "https://www.launchfa.st/blog/implement-basic-authorization-astro"
author: "Rishi Raj Jain"
created_at: 2025-07-16T10:00:00.000Z
updated_at: 2026-07-02T00:00:00.000Z
keywords: "astro, authentication, basic auth, middleware, authorization, security, web development"
---

> **Site index for agents**
> Fetch https://www.launchfa.st/llms.txt to discover every page on this site.
> Every page is also available as Markdown by appending `.md` to its URL.

<img width="1600" height="900" alt="How to Implement Basic Authorization in Astro" decoding="async" loading="eager" class="mt-4 border rounded-sm bg-cover bg-center bg-no-repeat transform will-change-auto" src="https://ik.imagekit.io/vjeqenuhn/launchfast-website/basic-auth-astro.png" />

<a href="/#pricing" class="rounded-full break-words text-xs border text-black px-4 py-2 max-w-max text-center no-underline hover:bg-black hover:text-white">
  ℹ️&nbsp;&nbsp;Available today with LaunchFast Starter Kits</a>
</div>

When building web applications, there are times when you need to protect your routes before launching to production. Whether you're working on a client project that needs to be hidden from the public or you want to add a simple authentication layer to your development environment, **basic authorization** is a quick and effective solution.

In this guide, we'll walk through how to implement basic authentication in your Astro application using middleware. This approach is perfect for temporary protection during development or staging phases.

## Table Of Contents

- [What is Basic Authentication?](#what-is-basic-authentication)
- [Step-by-Step Implementation](#step-by-step-implementation)
  - [Step 1: Create a new Astro application](#step-1-create-a-new-astro-application)
  - [Step 2: Integrate Node.js adapter in your Astro project](#step-2-integrate-nodejs-adapter-in-your-astro-project)
  - [Step 3: Create a Middleware File](#step-3-create-a-middleware-file)
  - [Step 4: Configure Protected Routes](#step-4-configure-protected-routes)
  - [Step 5: Set Up Environment Variables (Recommended)](#step-5-set-up-environment-variables-recommended)
- [How It Works](#how-it-works)
  - [1. Route Protection Logic](#1-route-protection-logic)
  - [2. Authentication Flow](#2-authentication-flow)

## What is Basic Authentication?

Basic authentication is a simple authentication scheme built into the HTTP protocol. It works by:

1. **Client Request**: The browser sends a request to a protected route
2. **Server Challenge**: The server responds with a `401 Unauthorized` status and a `WWW-Authenticate` header
3. **Browser Prompt**: The browser shows a login dialog to the user
4. **Credentials**: The user enters username/password, which gets encoded and sent with subsequent requests
5. **Validation**: The server validates the credentials and either allows or denies access

## Step-by-Step Implementation

### Step 1: Create a new Astro application

Let’s get started by creating a new Astro project. Execute the following command:

```bash
npm create astro@latest my-app
```

`npm create astro` is the recommended way to scaffold an Astro project quickly.

When prompted, choose:

- `Empty` when prompted on how to start the new project.
- `Yes` when prompted if you plan to write TypeScript.
- `Strict` when prompted how strict TypeScript should be.
- `Yes` when prompted to install dependencies.
- `Yes` when prompted to initialize a git repository.

Once that’s done, you can move into the project directory and start the app:

```bash
cd my-app
npm run dev
```

The app should be running on [localhost:4321](http://localhost:4321/).

### Step 2: Integrate Node.js adapter in your Astro project

To enable server-side rendering in your Astro project via the Node.js adapter, execute the following command:

```bash
npx astro add node
```

When prompted, choose the following:

- `Yes` when prompted whether to install the Node.js dependencies.
- `Yes` when prompted whether to make changes to the Astro configuration file.

This will install the necessary dependencies and update your `astro.config.mjs` file.

### Step 3: Create a Middleware File

Create a new file called `middleware.ts` in your `src/` directory with the following code:

```typescript
// src/middleware.ts
import { defineMiddleware } from 'astro:middleware'

// Define protected routes that require "basic authentication"
// (only to put the pages behind a basic auth before you actually launch your application to the world)
const PROTECTED_ROUTES = [
  // '/',
  // '/signin'
]

// Basic credentials (in production, use environment variables)
const VALID_CREDENTIALS = {
  username: 'admin',
  password: 'password123',
}

export const onRequest = defineMiddleware(async (context, next) => {
  const { url, request } = context
  const pathname = new URL(url).pathname
  
  // Check if the current route is protected
  const isProtectedRoute = PROTECTED_ROUTES.some((route) => 
    (route === '/' ? pathname === route : pathname.startsWith(route))
  )
  
  // For protected routes, check authentication
  if (isProtectedRoute) {
    const authHeader = request.headers.get('authorization')
    
    if (!authHeader || !authHeader.startsWith('Basic ')) {
      // Return 401 Unauthorized with WWW-Authenticate header
      return new Response('Authentication required', {
        status: 401,
        headers: {
          'WWW-Authenticate': 'Basic realm="Secure Area"',
          'Content-Type': 'text/plain',
        },
      })
    }
    
    // Extract and decode credentials
    const encodedCredentials = authHeader.substring(6)
    const decodedCredentials = atob(encodedCredentials)
    const [username, password] = decodedCredentials.split(':')
    
    // Validate credentials
    if (username !== VALID_CREDENTIALS.username || password !== VALID_CREDENTIALS.password) {
      return new Response('Invalid credentials', {
        status: 401,
        headers: {
          'WWW-Authenticate': 'Basic realm="Secure Area"',
          'Content-Type': 'text/plain',
        },
      })
    }
  }
  
  // Continue to the next middleware/route handler
  return next()
})
```

### Step 4: Configure Protected Routes

In the middleware file, you can specify which routes should be protected by uncommenting or adding routes to the `PROTECTED_ROUTES` array:

```typescript
// src/middleware.ts
const PROTECTED_ROUTES = [
  '/',           // Protect the homepage
  '/admin',      // Protect all routes starting with /admin
  '/dashboard',  // Protect all routes starting with /dashboard
  '/api',        // Protect all API routes
]
```

### Step 5: Set Up Environment Variables (Recommended)

For production use, it's better to use environment variables instead of hardcoded credentials. Create a `.env` file:

```bash
# .env

BASIC_AUTH_USERNAME=admin
BASIC_AUTH_PASSWORD=your-secure-password
```

Then update the middleware to use these environment variables:

```typescript
// middleware.ts
const VALID_CREDENTIALS = {
  username: import.meta.env.BASIC_AUTH_USERNAME || 'admin',
  password: import.meta.env.BASIC_AUTH_PASSWORD || 'password123',
}
```

## How It Works

### 1. Route Protection Logic

The middleware checks if the current route is in the `PROTECTED_ROUTES` array:

```typescript
const isProtectedRoute = PROTECTED_ROUTES.some((route) => 
  (route === '/' ? pathname === route : pathname.startsWith(route))
)
```

This allows for flexible route matching:
- Exact matches: `'/'` matches only the homepage
- Prefix matches: `'/admin'` matches `/admin`, `/admin/users`, `/admin/settings`, etc.

### 2. Authentication Flow

When a user visits a protected route:

1. **No Auth Header**: If no `Authorization` header is present, the server returns a `401` response with a `WWW-Authenticate` header
2. **Browser Prompt**: The browser shows a login dialog
3. **Credentials Sent**: User enters credentials, browser sends them encoded in base64
4. **Validation**: Server decodes and validates the credentials
5. **Access Granted/Denied**: If valid, the request continues; if invalid, another `401` is returned

## Conclusion

Basic authentication in Astro is a straightforward way to protect your routes during development or staging. While it's not suitable for production user authentication, it's perfect for:

- **Development Protection**: Hide work-in-progress features
- **Client Demos**: Protect client projects before launch
- **Staging Environments**: Secure staging sites
- **Admin Areas**: Quick protection for admin interfaces

The middleware approach we've implemented is clean, efficient, and easy to customize for your specific needs. Remember to use environment variables for credentials and consider more robust authentication solutions for production applications.
