> ## Documentation Index
> Fetch the complete documentation index at: https://docs.go-mizu.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Basic Auth

> HTTP Basic Authentication middleware for protecting routes with username/password.

## Overview

The `basicauth` middleware provides HTTP Basic Authentication, a simple authentication scheme built into the HTTP protocol. It prompts users for a username and password, which are sent with each request.

Use it when you need:

* Simple password protection for admin areas
* Quick authentication for internal tools
* Development/staging environment protection

## Installation

```go theme={null}
import "github.com/go-mizu/mizu/middlewares/basicauth"
```

## Quick Start

```go theme={null}
app := mizu.New()

// Define credentials
credentials := map[string]string{
    "admin": "secret",
    "user":  "password",
}

// Protect all routes
app.Use(basicauth.New(credentials))

// Or protect specific routes
app.Get("/admin", adminHandler, basicauth.New(credentials))
```

## Configuration

### Options

| Option         | Type                    | Default        | Description                                  |
| -------------- | ----------------------- | -------------- | -------------------------------------------- |
| `Realm`        | `string`                | `"Restricted"` | Authentication realm shown in browser prompt |
| `Validator`    | `ValidatorFunc`         | -              | Custom function to validate credentials      |
| `ErrorHandler` | `func(*mizu.Ctx) error` | -              | Custom handler for auth failures             |

### ValidatorFunc

```go theme={null}
type ValidatorFunc func(username, password string) bool
```

## Examples

### Static Credentials

```go theme={null}
credentials := basicauth.Accounts{
    "admin": "secret123",
    "api":   "token456",
}

app.Use(basicauth.New(credentials))
```

### Custom Realm

```go theme={null}
app.Use(basicauth.WithRealm("Admin Area", map[string]string{
    "admin": "secret",
}))
```

### Custom Validator

Validate against a database or external service:

```go theme={null}
app.Use(basicauth.WithValidator(func(user, pass string) bool {
    // Query database
    dbUser, err := db.GetUser(user)
    if err != nil {
        return false
    }

    // Verify password (use proper hashing!)
    return bcrypt.CompareHashAndPassword(
        []byte(dbUser.PasswordHash),
        []byte(pass),
    ) == nil
}))
```

### Custom Error Handler

```go theme={null}
app.Use(basicauth.WithOptions(basicauth.Options{
    Validator: func(user, pass string) bool {
        return user == "admin" && pass == "secret"
    },
    ErrorHandler: func(c *mizu.Ctx) error {
        return c.JSON(401, map[string]string{
            "error": "Invalid credentials",
        })
    },
}))
```

### Route-Specific Protection

```go theme={null}
// Public routes
app.Get("/", publicHandler)
app.Get("/about", aboutHandler)

// Protected admin routes
adminAuth := basicauth.New(map[string]string{"admin": "secret"})
app.Get("/admin", adminDashboard, adminAuth)
app.Get("/admin/users", adminUsers, adminAuth)
```

### Group Protection

```go theme={null}
admin := app.Group("/admin")
admin.Use(basicauth.New(map[string]string{"admin": "secret"}))

admin.Get("/", adminDashboard)
admin.Get("/users", adminUsers)
admin.Post("/users", createUser)
```

## API Reference

### Functions

```go theme={null}
// New creates middleware with static credentials
func New(credentials map[string]string) mizu.Middleware

// WithValidator creates middleware with custom validator
func WithValidator(fn ValidatorFunc) mizu.Middleware

// WithRealm creates middleware with custom realm
func WithRealm(realm string, credentials map[string]string) mizu.Middleware

// WithOptions creates middleware with full configuration
func WithOptions(opts Options) mizu.Middleware
```

### Types

```go theme={null}
// Accounts is a convenience type for credentials
type Accounts map[string]string
```

## Technical Details

The basicauth middleware implements HTTP Basic Authentication according to RFC 7617. Here are the key implementation details:

### Authentication Flow

1. **Header Extraction**: Extracts the `Authorization` header from the incoming request
2. **Scheme Validation**: Verifies the header starts with "Basic " prefix
3. **Base64 Decoding**: Decodes the base64-encoded credentials using `base64.StdEncoding.DecodeString()`
4. **Credential Parsing**: Splits the decoded string on the first colon (`:`) to separate username and password
5. **Validation**: Calls the configured validator function to verify credentials
6. **Response**: Either proceeds to the next handler or returns 401 Unauthorized with `WWW-Authenticate` header

### Security Features

**Constant-Time Comparison**: The built-in validator uses `secureCompare()` function to prevent timing attacks:

```go theme={null}
func secureCompare(a, b string) bool {
    // Hash both strings to ensure constant time comparison
    // even for strings of different lengths
    aHash := sha256.Sum256([]byte(a))
    bHash := sha256.Sum256([]byte(b))
    return subtle.ConstantTimeCompare(aHash[:], bHash[:]) == 1
}
```

This approach:

* Hashes both strings using SHA-256 to normalize lengths
* Uses `crypto/subtle.ConstantTimeCompare()` to prevent timing side-channels
* Protects against timing attacks that could leak password information

**WWW-Authenticate Header**: On authentication failure, the middleware sets the `WWW-Authenticate` header with the configured realm, prompting the browser to display a login dialog.

### Error Handling

The middleware returns 401 Unauthorized in these cases:

* Missing `Authorization` header
* Invalid authorization scheme (not "Basic")
* Invalid base64 encoding
* Malformed credentials (no colon separator)
* Validator function returns false

Custom error handlers can be provided via `Options.ErrorHandler` to customize the response format (e.g., JSON instead of plain text).

## Security Considerations

1. **Always use HTTPS** - Basic auth sends credentials base64-encoded (not encrypted)
2. **Use strong passwords** - Avoid dictionary words and short passwords
3. **Hash stored passwords** - Never store plain-text passwords in your validator
4. **Consider rate limiting** - Combine with `ratelimit` to prevent brute force attacks
5. **Timing attacks** - The built-in validator uses constant-time comparison

## Best Practices

* Use Basic Auth for simple internal tools, not production user-facing auth
* Combine with HTTPS redirect middleware
* Add rate limiting to prevent brute force attacks
* Use Bearer auth or session-based auth for APIs

## Testing

The basicauth middleware includes comprehensive test coverage. Below are all test cases:

| Test Case                                       | Description                                      | Expected Behavior                                                |
| ----------------------------------------------- | ------------------------------------------------ | ---------------------------------------------------------------- |
| **TestNew/allows valid credentials**            | Valid username and password provided             | Returns 200 OK and allows request through                        |
| **TestNew/rejects invalid password**            | Valid username with incorrect password           | Returns 401 Unauthorized                                         |
| **TestNew/rejects unknown user**                | Non-existent username provided                   | Returns 401 Unauthorized                                         |
| **TestNew/rejects missing auth**                | No Authorization header present                  | Returns 401 Unauthorized with WWW-Authenticate header            |
| **TestWithValidator**                           | Custom validator function with valid credentials | Returns 200 OK when validator returns true                       |
| **TestWithRealm**                               | Custom realm configuration                       | Returns 401 with WWW-Authenticate header containing custom realm |
| **TestWithOptions\_ErrorHandler**               | Custom error handler on auth failure             | Calls custom error handler returning JSON response               |
| **TestWithOptions\_InvalidAuth/not basic**      | Authorization header with Bearer scheme          | Returns 401 Unauthorized                                         |
| **TestWithOptions\_InvalidAuth/invalid base64** | Malformed base64 in Authorization header         | Returns 401 Unauthorized                                         |
| **TestWithOptions\_InvalidAuth/no colon**       | Base64 credentials without colon separator       | Returns 401 Unauthorized                                         |
| **TestWithOptions\_Panics**                     | Creating middleware without validator            | Panics with error message                                        |
| **TestSecureCompare/password\_password**        | Comparing identical strings                      | Returns true                                                     |
| **TestSecureCompare/password\_different**       | Comparing different strings                      | Returns false                                                    |
| **TestSecureCompare/short\_longpassword**       | Comparing strings of different lengths           | Returns false                                                    |
| **TestSecureCompare/empty\_empty**              | Comparing empty strings                          | Returns true                                                     |

## Related Middlewares

* [bearerauth](/middlewares/bearerauth) - Token-based authentication
* [keyauth](/middlewares/keyauth) - API key authentication
* [secure](/middlewares/secure) - HTTPS enforcement
* [ratelimit](/middlewares/ratelimit) - Rate limiting
