Skip to content

Commit 5435c4c

Browse files
committed
docs: clarify authentication middleware flow
- Updated middleware descriptions - Explained authentication flow - Clarified request context usage
1 parent 8da54e8 commit 5435c4c

File tree

3 files changed

+60
-12
lines changed

3 files changed

+60
-12
lines changed

routes/api/v1/_middleware.dart

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,20 @@ import 'package:dart_frog/dart_frog.dart';
22
import 'package:ht_api/src/middlewares/authentication_middleware.dart';
33

44
Handler middleware(Handler handler) {
5-
// This middleware applies authentication to all routes under /api/v1/.
6-
// It expects AuthTokenService to be provided by an ancestor middleware
7-
// (e.g., the global routes/_middleware.dart).
5+
// This middleware applies the `authenticationProvider` to all routes
6+
// under /api/v1/.
7+
//
8+
// The `authenticationProvider()` (from `lib/src/middlewares/authentication_middleware.dart`):
9+
// 1. Attempts to extract a Bearer token from the 'Authorization' header.
10+
// 2. Validates the token using the `AuthTokenService` (which must be
11+
// provided by an ancestor middleware, e.g., `routes/_middleware.dart`).
12+
// 3. Provides the resulting `User?` (nullable User object) into the request
13+
// context. This makes `context.read<User?>()` available downstream.
14+
//
15+
// IMPORTANT: `authenticationProvider()` itself does NOT block unauthenticated
16+
// requests. It simply makes the user's identity available if authentication
17+
// is successful. Stricter access control (blocking unauthenticated users)
18+
// is handled by `requireAuthentication()` middleware applied in more specific
19+
// route groups (e.g., `/api/v1/data/_middleware.dart`).
820
return handler.use(authenticationProvider());
921
}

routes/api/v1/data/_middleware.dart

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,32 @@ Middleware _modelValidationAndProviderMiddleware() {
6363
// Main middleware exported for the /api/v1/data route group.
6464
Handler middleware(Handler handler) {
6565
// This 'handler' is the actual route handler from index.dart or [id].dart.
66-
// The .use() method applies middleware in an "onion-skin" fashion.
67-
// The last .use() is the outermost layer.
68-
// So, requireAuthentication() runs first. If it passes,
69-
// _modelValidationAndProviderMiddleware() runs next.
70-
// If that passes, the actual route handler is executed.
66+
//
67+
// The .use() method applies middleware in an "onion-skin" fashion, where
68+
// the last .use() call in the chain represents the outermost middleware layer.
69+
// Therefore, the execution order for an incoming request is:
70+
//
71+
// 1. `requireAuthentication()`:
72+
// - This runs first. It relies on `authenticationProvider()` (from the
73+
// parent `/api/v1/_middleware.dart`) having already attempted to
74+
// authenticate the user and provide `User?` into the context.
75+
// - If `User` is null (no valid authentication), `requireAuthentication()`
76+
// throws an `UnauthorizedException`, and the request is aborted (usually
77+
// resulting in a 401 response via the global `errorHandler`).
78+
// - If `User` is present, the request proceeds to the next middleware.
79+
//
80+
// 2. `_modelValidationAndProviderMiddleware()`:
81+
// - This runs if `requireAuthentication()` passes.
82+
// - It validates the `?model=` query parameter and provides the
83+
// `ModelConfig` and `modelName` into the context.
84+
// - If model validation fails, it returns a 400 Bad Request response directly.
85+
// - If successful, it calls the next handler in the chain.
86+
//
87+
// 3. Actual Route Handler (from `index.dart` or `[id].dart`):
88+
// - This runs last, only if both preceding middlewares pass. It will have
89+
// access to a non-null `User`, `ModelConfig`, and `modelName` from the context.
90+
//
7191
return handler
72-
.use(_modelValidationAndProviderMiddleware())
73-
.use(requireAuthentication());
92+
.use(_modelValidationAndProviderMiddleware()) // Applied second (inner)
93+
.use(requireAuthentication()); // Applied first (outermost)
7494
}

routes/api/v1/users/[userId]/settings/_middleware.dart

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,23 @@ import 'package:dart_frog/dart_frog.dart';
55
import 'package:ht_api/src/middlewares/authentication_middleware.dart';
66

77
Handler middleware(Handler handler) {
8-
// Apply requireAuthentication to protect all settings routes.
9-
// This ensures that context.read<User>() will be non-null in these handlers.
8+
// Apply `requireAuthentication()` to protect all settings routes within the
9+
// /api/v1/users/[userId]/settings/ path.
10+
//
11+
// This middleware relies on `authenticationProvider()` (applied in the parent
12+
// `/api/v1/_middleware.dart`) to have already:
13+
// 1. Attempted to authenticate the user from a Bearer token.
14+
// 2. Provided `User?` (nullable User) into the request context.
15+
//
16+
// `requireAuthentication()` then checks this `User?` from the context:
17+
// - If `User` is null (meaning no valid authentication was established by
18+
// `authenticationProvider`), it throws an `UnauthorizedException`.
19+
// This typically results in a 401 HTTP response via the global `errorHandler`.
20+
// - If `User` is present (not null), the request is allowed to proceed to the
21+
// actual route handler (e.g., display.dart, language.dart).
22+
//
23+
// This ensures that all settings endpoints are strictly accessible only by
24+
// authenticated users, and `context.read<User>()` (non-nullable) can be
25+
// safely used within these route handlers.
1026
return handler.use(requireAuthentication());
1127
}

0 commit comments

Comments
 (0)