优化登录逻辑的实现,将认证请求和token验证的处理分成两个逻辑文件。新增交叉评查任务列表的页面(尚未对接真实数据)。
This commit is contained in:
@@ -0,0 +1,182 @@
|
||||
# 认证模块 (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)
|
||||
Reference in New Issue
Block a user