409 lines
18 KiB
Markdown
409 lines
18 KiB
Markdown
# 认证系统前端实现
|
||
|
||
<cite>
|
||
**本文档引用的文件**
|
||
- [frontend/app/api/auth/[...nextauth]/route.ts](file://frontend/app/api/auth/[...nextauth]/route.ts)
|
||
- [frontend/lib/auth.ts](file://frontend/lib/auth.ts)
|
||
- [frontend/types/next-auth.d.ts](file://frontend/types/next-auth.d.ts)
|
||
- [frontend/components/providers.tsx](file://frontend/components/providers.tsx)
|
||
- [frontend/lib/api.ts](file://frontend/lib/api.ts)
|
||
- [frontend/app/(auth)/layout.tsx](file://frontend/app/(auth)/layout.tsx)
|
||
- [frontend/app/(auth)/login/page.tsx](file://frontend/app/(auth)/login/page.tsx)
|
||
- [frontend/app/(dashboard)/layout.tsx](file://frontend/app/(dashboard)/layout.tsx)
|
||
- [frontend/app/layout.tsx](file://frontend/app/layout.tsx)
|
||
- [frontend/components/layout/header.tsx](file://frontend/components/layout/header.tsx)
|
||
- [frontend/app/(dashboard)/dashboard/page.tsx](file://frontend/app/(dashboard)/dashboard/page.tsx)
|
||
- [frontend/package.json](file://frontend/package.json)
|
||
</cite>
|
||
|
||
## 目录
|
||
1. [简介](#简介)
|
||
2. [项目结构](#项目结构)
|
||
3. [核心组件](#核心组件)
|
||
4. [架构概览](#架构概览)
|
||
5. [详细组件分析](#详细组件分析)
|
||
6. [依赖关系分析](#依赖关系分析)
|
||
7. [性能考虑](#性能考虑)
|
||
8. [故障排除指南](#故障排除指南)
|
||
9. [结论](#结论)
|
||
|
||
## 简介
|
||
|
||
本文件档详细说明了基于 NextAuth.js 的前端认证系统实现,包括 NextAuth.js 集成配置、会话管理、用户状态同步机制、认证提供者配置、OAuth 流程和 JWT 令牌处理。文档还涵盖了路由保护机制、权限验证、用户状态持久化、API 客户端认证头设置、请求拦截和错误处理,以及登录状态管理、会话过期处理和安全最佳实践。
|
||
|
||
## 项目结构
|
||
|
||
前端认证系统主要分布在以下目录和文件中:
|
||
|
||
- NextAuth 路由处理器:`frontend/app/api/auth/[...nextauth]/route.ts`
|
||
- NextAuth 配置:`frontend/lib/auth.ts`
|
||
- 类型声明扩展:`frontend/types/next-auth.d.ts`
|
||
- 全局 Provider 包装:`frontend/components/providers.tsx`
|
||
- API 客户端封装:`frontend/lib/api.ts`
|
||
- 登录页面:`frontend/app/(auth)/login/page.tsx`
|
||
- 仪表盘布局保护:`frontend/app/(dashboard)/layout.tsx`
|
||
- 根布局与 Provider 注入:`frontend/app/layout.tsx`
|
||
- 头部组件与登出:`frontend/components/layout/header.tsx`
|
||
- 仪表盘首页与会话使用:`frontend/app/(dashboard)/dashboard/page.tsx`
|
||
- 依赖包配置:`frontend/package.json`
|
||
|
||
```mermaid
|
||
graph TB
|
||
subgraph "前端应用"
|
||
A["根布局<br/>app/layout.tsx"]
|
||
B["全局Provider<br/>components/providers.tsx"]
|
||
C["NextAuth路由<br/>app/api/auth/[...nextauth]/route.ts"]
|
||
D["NextAuth配置<br/>lib/auth.ts"]
|
||
E["类型声明<br/>types/next-auth.d.ts"]
|
||
F["API客户端<br/>lib/api.ts"]
|
||
G["登录页面<br/>app/(auth)/login/page.tsx"]
|
||
H["仪表盘布局<br/>app/(dashboard)/layout.tsx"]
|
||
I["头部组件<br/>components/layout/header.tsx"]
|
||
J["仪表盘首页<br/>app/(dashboard)/dashboard/page.tsx"]
|
||
end
|
||
A --> B
|
||
B --> C
|
||
C --> D
|
||
D --> E
|
||
D --> F
|
||
G --> D
|
||
H --> D
|
||
I --> D
|
||
J --> F
|
||
```
|
||
|
||
**图表来源**
|
||
- [frontend/app/layout.tsx:22-36](file://frontend/app/layout.tsx#L22-L36)
|
||
- [frontend/components/providers.tsx:6-8](file://frontend/components/providers.tsx#L6-L8)
|
||
- [frontend/app/api/auth/[...nextauth]/route.ts:1-7](file://frontend/app/api/auth/[...nextauth]/route.ts#L1-L7)
|
||
- [frontend/lib/auth.ts:5-55](file://frontend/lib/auth.ts#L5-L55)
|
||
- [frontend/types/next-auth.d.ts:1-26](file://frontend/types/next-auth.d.ts#L1-L26)
|
||
- [frontend/lib/api.ts:23-57](file://frontend/lib/api.ts#L23-L57)
|
||
- [frontend/app/(auth)/login/page.tsx:19-42](file://frontend/app/(auth)/login/page.tsx#L19-L42)
|
||
- [frontend/app/(dashboard)/layout.tsx:7-26](file://frontend/app/(dashboard)/layout.tsx#L7-L26)
|
||
- [frontend/components/layout/header.tsx:7-29](file://frontend/components/layout/header.tsx#L7-L29)
|
||
- [frontend/app/(dashboard)/dashboard/page.tsx:20-44](file://frontend/app/(dashboard)/dashboard/page.tsx#L20-L44)
|
||
|
||
**章节来源**
|
||
- [frontend/app/layout.tsx:22-36](file://frontend/app/layout.tsx#L22-L36)
|
||
- [frontend/components/providers.tsx:6-8](file://frontend/components/providers.tsx#L6-L8)
|
||
- [frontend/app/api/auth/[...nextauth]/route.ts:1-7](file://frontend/app/api/auth/[...nextauth]/route.ts#L1-L7)
|
||
- [frontend/lib/auth.ts:5-55](file://frontend/lib/auth.ts#L5-L55)
|
||
- [frontend/types/next-auth.d.ts:1-26](file://frontend/types/next-auth.d.ts#L1-L26)
|
||
- [frontend/lib/api.ts:23-57](file://frontend/lib/api.ts#L23-L57)
|
||
- [frontend/app/(auth)/login/page.tsx:19-42](file://frontend/app/(auth)/login/page.tsx#L19-L42)
|
||
- [frontend/app/(dashboard)/layout.tsx:7-26](file://frontend/app/(dashboard)/layout.tsx#L7-L26)
|
||
- [frontend/components/layout/header.tsx:7-29](file://frontend/components/layout/header.tsx#L7-L29)
|
||
- [frontend/app/(dashboard)/dashboard/page.tsx:20-44](file://frontend/app/(dashboard)/dashboard/page.tsx#L20-L44)
|
||
|
||
## 核心组件
|
||
|
||
### NextAuth.js 集成配置
|
||
|
||
NextAuth.js 在本项目中的核心配置位于 `lib/auth.ts`,采用凭据式认证提供者,并通过回调函数将后端返回的访问令牌和用户标识写入 JWT 和会话对象中。配置要点如下:
|
||
|
||
- 凭据式提供者:接收邮箱和密码,调用后端 `/api/v1/auth/login` 接口进行认证。
|
||
- 会话策略:使用 JWT 策略,便于在客户端存储和传递访问令牌。
|
||
- 回调函数:
|
||
- `jwt`:当用户存在时,将 `accessToken` 和 `id` 写入 JWT。
|
||
- `session`:将 `accessToken` 和 `id` 同步到会话对象,供前端组件使用。
|
||
- 登录页重定向:登录失败时自动跳转至 `/login`。
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
Start(["开始"]) --> Validate["校验凭据<br/>邮箱/密码"]
|
||
Validate --> CallAPI["调用后端登录接口<br/>/api/v1/auth/login"]
|
||
CallAPI --> HasToken{"返回包含访问令牌?"}
|
||
HasToken --> |是| BuildUser["构建用户对象<br/>包含id/name/email/accessToken"]
|
||
HasToken --> |否| ReturnNull["返回空"]
|
||
BuildUser --> JWT["写入JWT回调<br/>保存accessToken/id"]
|
||
JWT --> Session["写入会话回调<br/>同步accessToken/id"]
|
||
Session --> Done(["完成"])
|
||
ReturnNull --> Done
|
||
```
|
||
|
||
**图表来源**
|
||
- [frontend/lib/auth.ts:13-32](file://frontend/lib/auth.ts#L13-L32)
|
||
- [frontend/lib/auth.ts:39-50](file://frontend/lib/auth.ts#L39-L50)
|
||
|
||
**章节来源**
|
||
- [frontend/lib/auth.ts:5-55](file://frontend/lib/auth.ts#L5-L55)
|
||
|
||
### NextAuth 路由处理器
|
||
|
||
NextAuth 路由处理器位于 `app/api/auth/[...nextauth]/route.ts`,负责将 NextAuth 实例导出为 GET 和 POST 处理器,以支持 NextAuth 的所有认证流程。
|
||
|
||
**章节来源**
|
||
- [frontend/app/api/auth/[...nextauth]/route.ts:1-7](file://frontend/app/api/auth/[...nextauth]/route.ts#L1-L7)
|
||
|
||
### 类型声明扩展
|
||
|
||
为了在 TypeScript 中正确识别自定义的 `accessToken` 和 `id` 字段,需要扩展 NextAuth 的类型声明。类型声明位于 `types/next-auth.d.ts`,确保在使用 `useSession` 时能获得完整的类型提示。
|
||
|
||
**章节来源**
|
||
- [frontend/types/next-auth.d.ts:1-26](file://frontend/types/next-auth.d.ts#L1-L26)
|
||
|
||
### 全局 Provider 包装
|
||
|
||
根布局通过 `components/providers.tsx` 将 `SessionProvider` 注入到整个应用中,使所有子组件能够使用 `useSession`、`signIn`、`signOut` 等 NextAuth 提供的 Hook 和方法。
|
||
|
||
**章节来源**
|
||
- [frontend/app/layout.tsx:22-36](file://frontend/app/layout.tsx#L22-L36)
|
||
- [frontend/components/providers.tsx:6-8](file://frontend/components/providers.tsx#L6-L8)
|
||
|
||
### API 客户端封装
|
||
|
||
API 客户端位于 `lib/api.ts`,统一处理认证头设置、请求拦截和错误处理。其特点包括:
|
||
|
||
- 基础 URL:从环境变量 `NEXT_PUBLIC_API_URL` 获取后端地址。
|
||
- 认证头设置:当传入 token 时,在请求头添加 `Authorization: Bearer ${token}`。
|
||
- 错误处理:对非 2xx 响应抛出错误,错误消息来自后端 JSON 或默认文本。
|
||
- 功能模块:
|
||
- 认证:注册、登录、获取当前用户信息。
|
||
- 查询:列表、创建、更新、删除。
|
||
- 引用:列表、统计。
|
||
- 报告:导出 CSV。
|
||
|
||
```mermaid
|
||
sequenceDiagram
|
||
participant UI as "UI组件"
|
||
participant API as "API客户端"
|
||
participant BE as "后端服务"
|
||
UI->>API : 调用带token的方法
|
||
API->>API : 设置Authorization头
|
||
API->>BE : 发送HTTP请求
|
||
BE-->>API : 返回JSON响应
|
||
API->>API : 检查响应状态
|
||
API-->>UI : 成功返回数据或抛出错误
|
||
```
|
||
|
||
**图表来源**
|
||
- [frontend/lib/api.ts:3-21](file://frontend/lib/api.ts#L3-L21)
|
||
- [frontend/lib/api.ts:23-57](file://frontend/lib/api.ts#L23-L57)
|
||
|
||
**章节来源**
|
||
- [frontend/lib/api.ts:1-58](file://frontend/lib/api.ts#L1-L58)
|
||
|
||
### 登录页面与认证流程
|
||
|
||
登录页面位于 `app/(auth)/login/page.tsx`,使用 `signIn('credentials', {...})` 触发 NextAuth 的凭据式认证流程。表单提交后,若认证成功则跳转到 `/dashboard` 并刷新页面;若失败则显示错误信息。
|
||
|
||
**章节来源**
|
||
- [frontend/app/(auth)/login/page.tsx:19-42](file://frontend/app/(auth)/login/page.tsx#L19-L42)
|
||
|
||
### 仪表盘布局保护
|
||
|
||
仪表盘布局 `app/(dashboard)/layout.tsx` 使用 `getServerSession(authOptions)` 在服务端检查会话有效性,未登录则重定向到 `/login`。这确保了前端路由的服务器端保护。
|
||
|
||
**章节来源**
|
||
- [frontend/app/(dashboard)/layout.tsx:7-26](file://frontend/app/(dashboard)/layout.tsx#L7-L26)
|
||
|
||
### 头部组件与登出
|
||
|
||
头部组件 `components/layout/header.tsx` 使用 `useSession` 获取当前会话信息,并通过 `signOut({ callbackUrl: '/login' })` 实现登出功能,登出后自动跳转到登录页。
|
||
|
||
**章节来源**
|
||
- [frontend/components/layout/header.tsx:7-29](file://frontend/components/layout/header.tsx#L7-L29)
|
||
|
||
### 仪表盘首页与会话使用
|
||
|
||
仪表盘首页 `app/(dashboard)/dashboard/page.tsx` 使用 `useSession` 获取 `accessToken`,并在依赖变化时调用 API 客户端获取统计数据。该组件展示了如何在客户端读取 NextAuth 会话并将其用于 API 请求。
|
||
|
||
**章节来源**
|
||
- [frontend/app/(dashboard)/dashboard/page.tsx:20-44](file://frontend/app/(dashboard)/dashboard/page.tsx#L20-L44)
|
||
|
||
## 架构概览
|
||
|
||
整体认证架构由前端 NextAuth.js、后端认证接口和 API 客户端组成。前端通过 NextAuth 管理会话和令牌,API 客户端负责携带令牌与后端交互。
|
||
|
||
```mermaid
|
||
graph TB
|
||
subgraph "前端"
|
||
U["用户界面"]
|
||
NA["NextAuth.js<br/>凭据式认证"]
|
||
SP["SessionProvider<br/>全局会话注入"]
|
||
AC["API客户端<br/>fetchWithAuth"]
|
||
end
|
||
subgraph "后端"
|
||
AUTH["认证接口<br/>/api/v1/auth/*"]
|
||
DATA["业务接口<br/>/api/v1/*"]
|
||
end
|
||
U --> SP
|
||
SP --> NA
|
||
NA --> AC
|
||
AC --> AUTH
|
||
AC --> DATA
|
||
```
|
||
|
||
**图表来源**
|
||
- [frontend/lib/auth.ts:5-55](file://frontend/lib/auth.ts#L5-L55)
|
||
- [frontend/lib/api.ts:23-57](file://frontend/lib/api.ts#L23-L57)
|
||
- [frontend/app/api/auth/[...nextauth]/route.ts:1-7](file://frontend/app/api/auth/[...nextauth]/route.ts#L1-L7)
|
||
|
||
## 详细组件分析
|
||
|
||
### NextAuth.js 配置类图
|
||
|
||
```mermaid
|
||
classDiagram
|
||
class AuthOptions {
|
||
+providers
|
||
+session
|
||
+callbacks
|
||
+pages
|
||
}
|
||
class CredentialsProvider {
|
||
+name
|
||
+credentials
|
||
+authorize(credentials)
|
||
}
|
||
class JWTCallbacks {
|
||
+jwt({token, user})
|
||
}
|
||
class SessionCallbacks {
|
||
+session({session, token})
|
||
}
|
||
AuthOptions --> CredentialsProvider : "包含"
|
||
AuthOptions --> JWTCallbacks : "回调"
|
||
AuthOptions --> SessionCallbacks : "回调"
|
||
```
|
||
|
||
**图表来源**
|
||
- [frontend/lib/auth.ts:5-55](file://frontend/lib/auth.ts#L5-L55)
|
||
|
||
**章节来源**
|
||
- [frontend/lib/auth.ts:5-55](file://frontend/lib/auth.ts#L5-L55)
|
||
|
||
### 登录流程序列图
|
||
|
||
```mermaid
|
||
sequenceDiagram
|
||
participant 用户 as "用户"
|
||
participant 登录页 as "登录页面"
|
||
participant NextAuth as "NextAuth"
|
||
participant 后端 as "后端认证接口"
|
||
用户->>登录页 : 输入邮箱/密码并提交
|
||
登录页->>NextAuth : signIn('credentials', {email,password,redirect : false})
|
||
NextAuth->>后端 : POST /api/v1/auth/login
|
||
后端-->>NextAuth : 返回access_token和用户信息
|
||
NextAuth-->>登录页 : 返回认证结果
|
||
登录页->>登录页 : 成功则跳转并刷新页面
|
||
```
|
||
|
||
**图表来源**
|
||
- [frontend/app/(auth)/login/page.tsx:26-42](file://frontend/app/(auth)/login/page.tsx#L26-L42)
|
||
- [frontend/lib/auth.ts:13-32](file://frontend/lib/auth.ts#L13-L32)
|
||
- [frontend/lib/api.ts:30-35](file://frontend/lib/api.ts#L30-L35)
|
||
|
||
**章节来源**
|
||
- [frontend/app/(auth)/login/page.tsx:19-42](file://frontend/app/(auth)/login/page.tsx#L19-L42)
|
||
- [frontend/lib/auth.ts:13-32](file://frontend/lib/auth.ts#L13-L32)
|
||
- [frontend/lib/api.ts:23-35](file://frontend/lib/api.ts#L23-L35)
|
||
|
||
### 会话管理与状态同步
|
||
|
||
会话管理通过 NextAuth 的回调函数实现 JWT 与会话对象之间的双向同步,确保前端组件可以稳定地读取 `accessToken` 和用户标识。
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
A["用户登录成功"] --> B["JWT回调<br/>写入accessToken/id"]
|
||
B --> C["会话回调<br/>同步accessToken/id"]
|
||
C --> D["useSession读取会话"]
|
||
D --> E["API客户端携带令牌请求后端"]
|
||
```
|
||
|
||
**图表来源**
|
||
- [frontend/lib/auth.ts:39-50](file://frontend/lib/auth.ts#L39-L50)
|
||
- [frontend/lib/api.ts:12-14](file://frontend/lib/api.ts#L12-L14)
|
||
|
||
**章节来源**
|
||
- [frontend/lib/auth.ts:39-50](file://frontend/lib/auth.ts#L39-L50)
|
||
- [frontend/lib/api.ts:12-14](file://frontend/lib/api.ts#L12-L14)
|
||
|
||
### 路由保护机制
|
||
|
||
- 服务器端保护:仪表盘布局在服务端检查会话,未登录直接重定向到登录页。
|
||
- 客户端保护:通过 `useSession` 在客户端读取会话状态,控制页面渲染和导航。
|
||
|
||
**章节来源**
|
||
- [frontend/app/(dashboard)/layout.tsx:7-26](file://frontend/app/(dashboard)/layout.tsx#L7-L26)
|
||
- [frontend/app/(dashboard)/dashboard/page.tsx:20-44](file://frontend/app/(dashboard)/dashboard/page.tsx#L20-L44)
|
||
|
||
### 权限验证与用户状态持久化
|
||
|
||
- 权限验证:通过 `useSession` 获取的 `accessToken` 控制 API 请求权限。
|
||
- 用户状态持久化:NextAuth 的 JWT 策略将用户信息持久化在客户端,避免每次刷新丢失。
|
||
|
||
**章节来源**
|
||
- [frontend/lib/auth.ts:35-50](file://frontend/lib/auth.ts#L35-L50)
|
||
- [frontend/app/(dashboard)/dashboard/page.tsx:20-44](file://frontend/app/(dashboard)/dashboard/page.tsx#L20-L44)
|
||
|
||
### API 客户端认证头设置与错误处理
|
||
|
||
- 认证头设置:在 `fetchWithAuth` 中根据是否传入 token 自动添加 `Authorization` 头。
|
||
- 请求拦截:统一处理 Content-Type 和自定义请求头。
|
||
- 错误处理:对非 2xx 响应抛出错误,错误消息来自后端 JSON 或默认文本。
|
||
|
||
**章节来源**
|
||
- [frontend/lib/api.ts:3-21](file://frontend/lib/api.ts#L3-L21)
|
||
|
||
## 依赖关系分析
|
||
|
||
前端认证系统的关键依赖关系如下:
|
||
|
||
- NextAuth.js 版本:`package.json` 中声明为 `^4.24.14`。
|
||
- 全局 Provider:根布局通过 `components/providers.tsx` 注入 `SessionProvider`。
|
||
- NextAuth 路由:`app/api/auth/[...nextauth]/route.ts` 导出 NextAuth 实例。
|
||
- 类型扩展:`types/next-auth.d.ts` 扩展 NextAuth 类型,确保类型安全。
|
||
- API 客户端:`lib/api.ts` 统一处理认证头和错误处理。
|
||
|
||
```mermaid
|
||
graph TB
|
||
P["package.json<br/>依赖声明"] --> NA["next-auth@^4.24.14"]
|
||
L["lib/auth.ts<br/>NextAuth配置"] --> NA
|
||
R["app/api/auth/[...nextauth]/route.ts<br/>路由处理器"] --> L
|
||
T["types/next-auth.d.ts<br/>类型扩展"] --> NA
|
||
A["lib/api.ts<br/>API客户端"] --> L
|
||
S["components/providers.tsx<br/>SessionProvider"] --> NA
|
||
```
|
||
|
||
**图表来源**
|
||
- [frontend/package.json:21-22](file://frontend/package.json#L21-L22)
|
||
- [frontend/lib/auth.ts:1-3](file://frontend/lib/auth.ts#L1-L3)
|
||
- [frontend/app/api/auth/[...nextauth]/route.ts:1-2](file://frontend/app/api/auth/[...nextauth]/route.ts#L1-L2)
|
||
- [frontend/types/next-auth.d.ts:1](file://frontend/types/next-auth.d.ts#L1)
|
||
- [frontend/lib/api.ts:3](file://frontend/lib/api.ts#L3)
|
||
- [frontend/components/providers.tsx:3](file://frontend/components/providers.tsx#L3)
|
||
|
||
**章节来源**
|
||
- [frontend/package.json:11-27](file://frontend/package.json#L11-L27)
|
||
- [frontend/lib/auth.ts:1-3](file://frontend/lib/auth.ts#L1-L3)
|
||
- [frontend/app/api/auth/[...nextauth]/route.ts:1-2](file://frontend/app/api/auth/[...nextauth]/route.ts#L1-L2)
|
||
- [frontend/types/next-auth.d.ts:1](file://frontend/types/next-auth.d.ts#L1)
|
||
- [frontend/lib/api.ts:3](file://frontend/lib/api.ts#L3)
|
||
- [frontend/components/providers.tsx:3](file://frontend/components/providers.tsx#L3)
|
||
|
||
## 性能考虑
|
||
|
||
- 会话策略:使用 JWT 策略减少频繁的服务端会话查询,提升客户端响应速度。
|
||
- 请求复用:API 客户端统一处理认证头和错误,避免重复代码和网络开销。
|
||
- 依赖更新:在 `useEffect` 中仅在 `accessToken` 变化时触发数据加载,避免不必要的请求。
|
||
|
||
[本节为通用性能建议,不涉及具体文件分析]
|
||
|
||
## 故障排除指南
|
||
|
||
- 登录失败:检查登录页面的错误提示逻辑,确认 `signIn('credentials')` 返回的错误信息。
|
||
- 会话缺失:确认根布局已注入 `SessionProvider`,且 `useSession` 在受保护组件中正确使用。
|
||
- API 请求失败:检查 `fetchWithAuth` 的错误处理逻辑,确认后端返回的错误消息格式。
|
||
- 服务器端重定向:确认仪表盘布局的 `getServerSession` 检查逻辑,确保未登录时正确重定向。
|
||
|
||
**章节来源**
|
||
- [frontend/app/(auth)/login/page.tsx:36-42](file://frontend/app/(auth)/login/page.tsx#L36-L42)
|
||
- [frontend/app/layout.tsx:32](file://frontend/app/layout.tsx#L32)
|
||
- [frontend/lib/api.ts:16-21](file://frontend/lib/api.ts#L16-L21)
|
||
- [frontend/app/(dashboard)/layout.tsx:12-15](file://frontend/app/(dashboard)/layout.tsx#L12-L15)
|
||
|
||
## 结论
|
||
|
||
本认证系统通过 NextAuth.js 的凭据式认证、JWT 会话策略和统一的 API 客户端封装,实现了完整的前端认证流程。系统在服务器端和客户端分别提供了路由保护,结合类型扩展确保了开发体验和运行时的类型安全。通过合理的错误处理和会话管理,系统具备良好的可维护性和扩展性。 |