Files
leaudit-platform-frontend/app/api/login/README.md
T

182 lines
5.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 认证模块 (Authentication Module)
这个文件夹包含了整个应用的用户认证和会话管理功能。
## 📁 文件结构
```
app/api/login/
├── README.md # 本文档
├── auth.server.ts # 🔐 认证核心实现
├── auth-exports.server.ts # 📤 认证函数导出入口
├── oauth-client.ts # 🌐 OAuth2.0 客户端
├── token-manager.server.ts # 🎫 Token 管理器
└── OAuth2.0认证协议集成指南.md # 📖 OAuth2.0 集成文档
```
## 🔧 核心文件说明
### `auth.server.ts` - 认证核心实现
包含所有认证相关的核心功能:
- **会话管理**: 基于 Cookie 的安全会话存储
- **用户认证**: 检查用户登录状态
- **Token 刷新**: 自动刷新过期的 OAuth Token
- **登录/登出**: 创建和销毁用户会话
主要函数:
- `getUserSession()` - 获取用户会话(带 Token 刷新)
- `createUserSession()` - 创建登录会话
- `logout()` - 销毁会话并登出
- `getSession()` - 获取原始会话对象
### `auth-exports.server.ts` - 导出入口
这个文件解决了 Remix + Vite 架构中的一个重要问题:
**问题**: 同构文件(.tsx)不能直接导入 .server.ts 文件
**原因**: 防止服务器端敏感代码被打包到客户端
**解决**: 通过这个 .server.ts 文件重新导出认证函数
```typescript
// ✅ 正确的导入方式
import { getUserSession } from "~/api/login/auth-exports.server";
// ❌ 错误的导入方式(会导致构建错误)
import { getUserSession } from "~/api/login/auth.server";
```
### `oauth-client.ts` - OAuth2.0 客户端
实现 OAuth2.0 认证协议的客户端功能:
- 生成授权 URL
- 获取访问令牌
- 获取用户信息
- 状态值生成和验证
### `token-manager.server.ts` - Token 管理
负责 OAuth Token 的生命周期管理:
- Token 有效期检查
- 自动刷新即将过期的 Token
- Token 错误处理
## 🚀 使用指南
### 在路由中检查用户认证
```typescript
// app/routes/some-route.tsx
import { getUserSession } from "~/api/login/auth-exports.server";
export async function loader({ request }: LoaderFunctionArgs) {
const { isAuthenticated, userRole } = await getUserSession(request);
if (!isAuthenticated) {
return redirect("/login");
}
// 检查权限
if (userRole !== 'developer') {
throw new Response("权限不足", { status: 403 });
}
return json({ userRole });
}
```
### 处理用户登出
```typescript
// app/routes/some-route.tsx
import { logout } from "~/api/login/auth-exports.server";
export async function action({ request }: ActionFunctionArgs) {
const formData = await request.formData();
if (formData.get("intent") === "logout") {
return logout(request);
}
return null;
}
```
### 创建登录会话
```typescript
// app/routes/callback.tsx
import { createUserSession } from "~/api/login/auth-exports.server";
export async function loader({ request }: LoaderFunctionArgs) {
// OAuth 认证成功后...
// 根据用户信息判断角色
const userRole = userInfo.username === "admin" ? "developer" : "common";
return createUserSession(true, userRole, "/dashboard");
}
```
## 🛡️ 安全特性
### Cookie 安全配置
```typescript
cookie: {
httpOnly: true, // 防止 XSS 攻击
sameSite: "lax", // CSRF 保护
secure: false, // 开发环境设为 false,生产环境应为 true
maxAge: 7200, // 2小时过期
}
```
### Token 自动刷新
- 检查 Token 是否即将过期(5分钟内)
- 自动使用 refresh_token 获取新的 access_token
- 刷新失败时自动登出用户
### 用户角色权限
- `common`: 普通用户,基本功能访问权限
- `developer`: 开发者/管理员,完整系统管理权限
## 🔄 OAuth2.0 登录流程
```mermaid
sequenceDiagram
participant User as 用户
participant App as 应用
participant IDaaS as IDaaS平台
User->>App: 访问受保护页面
App->>User: 重定向到 /login
User->>App: 点击"统一身份认证登录"
App->>IDaaS: 重定向到 IDaaS 登录页
User->>IDaaS: 完成登录
IDaaS->>App: 回调并返回 code
App->>IDaaS: 使用 code 获取 access_token
IDaaS->>App: 返回 access_token
App->>IDaaS: 使用 access_token 获取用户信息
IDaaS->>App: 返回用户信息
App->>App: 创建用户会话
App->>User: 重定向到目标页面
```
## 🚨 注意事项
### 开发环境配置
1. 确保 OAuth 配置正确(`app/config/api-config.ts`
2. IDaaS 平台中配置正确的回调地址
3. 检查 Cookie 的 `secure` 设置(开发环境为 `false`
### 生产环境部署
1. 使用环境变量管理敏感信息(secrets)
2. 启用 HTTPS 并设置 `secure: true`
3. 配置正确的域名和回调地址
4. 监控 Token 刷新日志
### 调试技巧
- 查看浏览器 Application 标签页中的 Cookies
- 检查服务器控制台的认证相关日志
- 使用 Remix Dev Tools 查看 loader 数据
## 📖 相关文档
- [OAuth2.0认证协议集成指南](./OAuth2.0认证协议集成指南.md)
- [Remix Session Storage 文档](https://remix.run/docs/en/main/utils/sessions)
- [Cookie Security Best Practices](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies)