oxidite 2.1.0

A modern, batteries-included web framework for Rust inspired by Laravel and Rails - Oxidite
Documentation
# API Keys Guide

Learn how to implement API key authentication in Oxidite.

## Installation

```toml
[dependencies]
oxidite = { version = "1.0", features = ["auth", "database"] }
```

## Setup

```rust
use oxidite::prelude::*;
use oxidite::db::DbPool;
use oxidite::auth::api_key::*;

#[tokio::main]
async fn main() -> Result<()> {
    let db = DbPool::connect(&std::env::var("DATABASE_URL")?).await?;
    
    let mut app = Router::new();
    
    // Protected route
    app.get("/api/data", get_data)
        .middleware(ApiKeyMiddleware::new(db.clone()));
    
    Server::new(app).listen("127.0.0.1:3000".parse()?).await
}
```

## Generate API Keys

```rust
use oxidite::auth::api_key::*;

async fn create_api_key(user_id: i64, db: &Database) -> Result<String> {
    let api_key = ApiKey::generate(user_id)?;
    api_key.save(db).await?;
    
    // Return the plain key to user (only shown once)
    Ok(api_key.key)
}
```

## Validate API Keys

```rust
// In middleware or handler
async fn validate_key(key: &str, db: &Database) -> Result<ApiKey> {
    ApiKey::validate(key, db).await
}
```

## Using API Keys

Clients send the API key in the `Authorization` header:

```bash
curl -H "Authorization: Bearer your-api-key" \
     http://localhost:3000/api/data
```

## Complete Example

```rust
use oxidite::prelude::*;
use oxidite::auth::api_key::*;

#[derive(Serialize)]
struct ApiKeyResponse {
    key: String,
    user_id: i64,
}

async fn create_key(
    State(db): State<Database>,
    Json(req): Json<CreateKeyRequest>,
) -> Result<Json<ApiKeyResponse>> {
    let api_key = ApiKey::generate(req.user_id)?;
    api_key.save(&db).await?;
    
    Ok(Json(ApiKeyResponse {
        key: api_key.key,
        user_id: api_key.user_id,
    }))
}

async fn protected_route(api_key: ApiKey) -> Result<Json<Data>> {
    // api_key.user_id available
    Ok(Json(Data { message: "Success!".into() }))
}
```

## Best Practices

1. Never log API keys
2. Hash keys before storing
3. Allow key rotation
4. Set expiration dates
5. Rate limit by API key

## Revoke Keys

```rust
async fn revoke_key(key_id: i64, db: &Database) -> Result<()> {
    ApiKey::delete(db, key_id).await
}
```