feat(auth): Add authentication middleware
This commit is contained in:
240
.docs/usage.md
240
.docs/usage.md
@@ -56,6 +56,109 @@ curl -X PUT http://localhost:8080/api/v1/data/123
|
||||
curl -X DELETE http://localhost:8080/api/v1/data/123
|
||||
```
|
||||
|
||||
## Authentication
|
||||
|
||||
### Using API Key Authentication
|
||||
|
||||
**Configuration:**
|
||||
```yaml
|
||||
security:
|
||||
auth:
|
||||
enabled: true
|
||||
header: "X-Api-Key"
|
||||
```
|
||||
|
||||
**Valid request:**
|
||||
```bash
|
||||
curl -H "X-Api-Key: your-secret-key" http://localhost:8080/api/v1/data
|
||||
```
|
||||
|
||||
**Invalid request (missing header):**
|
||||
```bash
|
||||
curl http://localhost:8080/api/v1/data
|
||||
# Returns: 401 Unauthorized
|
||||
```
|
||||
|
||||
### Using Bearer Token Authentication
|
||||
|
||||
**Configuration:**
|
||||
```yaml
|
||||
security:
|
||||
auth:
|
||||
enabled: true
|
||||
header: "Authorization"
|
||||
```
|
||||
|
||||
**Valid request:**
|
||||
```bash
|
||||
curl -H "Authorization: Bearer your-token-here" http://localhost:8080/api/v1/data
|
||||
```
|
||||
|
||||
### Path-Based Authentication Examples
|
||||
|
||||
#### All Paths Require Auth
|
||||
|
||||
**Configuration:**
|
||||
```yaml
|
||||
security:
|
||||
auth:
|
||||
enabled: true
|
||||
header: "X-Api-Key"
|
||||
path:
|
||||
include: []
|
||||
exclude: []
|
||||
```
|
||||
|
||||
All requests to this route require authentication.
|
||||
|
||||
#### Only Specific Paths Require Auth (Include)
|
||||
|
||||
**Configuration:**
|
||||
```yaml
|
||||
security:
|
||||
auth:
|
||||
enabled: true
|
||||
header: "X-Api-Key"
|
||||
path:
|
||||
include: ["/api/admin/*", "/api/users/*/profile"]
|
||||
exclude: []
|
||||
```
|
||||
|
||||
**Request examples:**
|
||||
```bash
|
||||
# Requires auth (matches include)
|
||||
curl -H "X-Api-Key: key" http://localhost:8080/api/admin/users
|
||||
curl -H "X-Api-Key: key" http://localhost:8080/api/users/123/profile
|
||||
|
||||
# No auth required (doesn't match include)
|
||||
curl http://localhost:8080/api/public/data
|
||||
curl http://localhost:8080/api/health
|
||||
```
|
||||
|
||||
#### All Paths Except Specific Ones Require Auth (Exclude)
|
||||
|
||||
**Configuration:**
|
||||
```yaml
|
||||
security:
|
||||
auth:
|
||||
enabled: true
|
||||
header: "X-Api-Key"
|
||||
path:
|
||||
include: []
|
||||
exclude: ["/api/health", "/api/public/*"]
|
||||
```
|
||||
|
||||
**Request examples:**
|
||||
```bash
|
||||
# No auth required (matches exclude)
|
||||
curl http://localhost:8080/api/health
|
||||
curl http://localhost:8080/api/public/data
|
||||
|
||||
# Requires auth (doesn't match exclude)
|
||||
curl -H "X-Api-Key: key" http://localhost:8080/api/users
|
||||
curl -H "X-Api-Key: key" http://localhost:8080/api/admin/settings
|
||||
```
|
||||
|
||||
## Route Examples
|
||||
|
||||
### Strip Prefix Example
|
||||
@@ -87,6 +190,9 @@ routes:
|
||||
strip_prefix:
|
||||
enabled: true
|
||||
prefix: "/public"
|
||||
security:
|
||||
auth:
|
||||
enabled: false
|
||||
|
||||
- id: "api-route"
|
||||
api: "api-001"
|
||||
@@ -94,15 +200,19 @@ routes:
|
||||
strip_prefix:
|
||||
enabled: true
|
||||
prefix: "/api/v1"
|
||||
security:
|
||||
auth:
|
||||
enabled: true
|
||||
header: "X-Api-Key"
|
||||
```
|
||||
|
||||
**Requests:**
|
||||
```bash
|
||||
# Public route - backend receives /status
|
||||
# Public route - no auth, backend receives /status
|
||||
curl http://localhost:8080/public/status
|
||||
|
||||
# API route - backend receives /users
|
||||
curl http://localhost:8080/api/v1/users
|
||||
# API route - requires auth, backend receives /users
|
||||
curl -H "X-Api-Key: key" http://localhost:8080/api/v1/users
|
||||
```
|
||||
|
||||
## Logging
|
||||
@@ -130,6 +240,27 @@ The gateway uses structured JSON logging via `masterlog`. All HTTP requests are
|
||||
}
|
||||
```
|
||||
|
||||
### Debug Logging
|
||||
|
||||
To enable detailed authentication logging, set DEBUG level in `main.go`:
|
||||
|
||||
```go
|
||||
masterlog.SetLevel(masterlog.LevelDebug)
|
||||
```
|
||||
|
||||
This will output detailed auth decision logs:
|
||||
|
||||
```json
|
||||
{
|
||||
"level": "debug",
|
||||
"msg": "AuthMiddleware: Checking if path requires auth",
|
||||
"path": "/api/v1/users",
|
||||
"requires_auth": true,
|
||||
"include": [],
|
||||
"exclude": ["/api/v1/public/*"]
|
||||
}
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Gateway fails to start
|
||||
@@ -146,6 +277,13 @@ cat ../gateway.yaml
|
||||
|
||||
3. Check logs for detailed error messages
|
||||
|
||||
### 401 Unauthorized
|
||||
|
||||
- Verify auth header is included
|
||||
- Check header name matches configuration (case-sensitive)
|
||||
- Verify path is not excluded from auth (check exclude patterns)
|
||||
- Enable DEBUG logging to see auth decision process
|
||||
|
||||
### 404 Not Found
|
||||
|
||||
- Verify the route path matches your request
|
||||
@@ -165,6 +303,22 @@ cat ../gateway.yaml
|
||||
- Remember that `/*` matches zero or more path segments
|
||||
- Check that multiple routes don't have conflicting patterns
|
||||
|
||||
### Auth not working as expected
|
||||
|
||||
1. Enable DEBUG logging to see auth decisions:
|
||||
```go
|
||||
masterlog.SetLevel(masterlog.LevelDebug)
|
||||
```
|
||||
|
||||
2. Check the logs for:
|
||||
- Whether the path requires auth
|
||||
- Whether the auth header is present
|
||||
- Which patterns are being matched
|
||||
|
||||
3. Verify your include/exclude patterns:
|
||||
- Wildcards end with `*`
|
||||
- Patterns are prefix-based (e.g., `/api/v1/public/test/*`)
|
||||
|
||||
## Performance Considerations
|
||||
|
||||
- The gateway uses Go's `httputil.ReverseProxy` for efficient proxying
|
||||
@@ -175,23 +329,57 @@ cat ../gateway.yaml
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### API Versioning
|
||||
### API Versioning with Auth
|
||||
|
||||
```yaml
|
||||
routes:
|
||||
- id: "v1-api"
|
||||
- id: "v1-public-api"
|
||||
api: "api-001"
|
||||
path: "/api/v1/public/*"
|
||||
strip_prefix:
|
||||
enabled: true
|
||||
prefix: "/api/v1/public"
|
||||
security:
|
||||
auth:
|
||||
enabled: false
|
||||
|
||||
- id: "v1-protected-api"
|
||||
api: "api-001"
|
||||
path: "/api/v1/*"
|
||||
strip_prefix:
|
||||
enabled: true
|
||||
prefix: "/api/v1"
|
||||
security:
|
||||
auth:
|
||||
enabled: true
|
||||
header: "X-Api-Key"
|
||||
```
|
||||
|
||||
- id: "v2-api"
|
||||
### Mixed Authentication
|
||||
|
||||
```yaml
|
||||
routes:
|
||||
- id: "user-api"
|
||||
api: "api-001"
|
||||
path: "/api/v2/*"
|
||||
strip_prefix:
|
||||
enabled: true
|
||||
prefix: "/api/v2"
|
||||
path: "/users/*"
|
||||
security:
|
||||
auth:
|
||||
enabled: true
|
||||
header: "X-Api-Key"
|
||||
path:
|
||||
include: []
|
||||
exclude: ["/users/login", "/users/register"]
|
||||
|
||||
- id: "admin-api"
|
||||
api: "api-001"
|
||||
path: "/admin/*"
|
||||
security:
|
||||
auth:
|
||||
enabled: true
|
||||
header: "Authorization"
|
||||
path:
|
||||
include: []
|
||||
exclude: []
|
||||
```
|
||||
|
||||
### Microservices Routing
|
||||
@@ -220,6 +408,10 @@ routes:
|
||||
strip_prefix:
|
||||
enabled: true
|
||||
prefix: "/users"
|
||||
security:
|
||||
auth:
|
||||
enabled: true
|
||||
header: "X-Api-Key"
|
||||
|
||||
- id: "orders-route"
|
||||
api: "order-api"
|
||||
@@ -227,28 +419,8 @@ routes:
|
||||
strip_prefix:
|
||||
enabled: true
|
||||
prefix: "/orders"
|
||||
security:
|
||||
auth:
|
||||
enabled: true
|
||||
header: "Authorization"
|
||||
```
|
||||
|
||||
### External API Proxy
|
||||
|
||||
```yaml
|
||||
targets:
|
||||
- id: "external-api"
|
||||
name: "External API"
|
||||
url: "https://api.external.com"
|
||||
|
||||
apis:
|
||||
- id: "external"
|
||||
host: "host-001"
|
||||
target: "external-api"
|
||||
|
||||
routes:
|
||||
- id: "external-proxy"
|
||||
api: "external"
|
||||
path: "/proxy/external/*"
|
||||
strip_prefix:
|
||||
enabled: true
|
||||
prefix: "/proxy/external"
|
||||
```
|
||||
|
||||
Request to `/proxy/external/users` becomes `/users` on the external API.
|
||||
|
||||
Reference in New Issue
Block a user