5.2 KiB
5.2 KiB
认证模块 (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 文件重新导出认证函数
// ✅ 正确的导入方式
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 错误处理
🚀 使用指南
在路由中检查用户认证
// 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 });
}
处理用户登出
// 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;
}
创建登录会话
// 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 安全配置
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 登录流程
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: 重定向到目标页面
🚨 注意事项
开发环境配置
- 确保 OAuth 配置正确(
app/config/api-config.ts) - IDaaS 平台中配置正确的回调地址
- 检查 Cookie 的
secure设置(开发环境为false)
生产环境部署
- 使用环境变量管理敏感信息(secrets)
- 启用 HTTPS 并设置
secure: true - 配置正确的域名和回调地址
- 监控 Token 刷新日志
调试技巧
- 查看浏览器 Application 标签页中的 Cookies
- 检查服务器控制台的认证相关日志
- 使用 Remix Dev Tools 查看 loader 数据