FoalTS 认证与访问控制快速入门指南
认证与授权基础概念
在构建现代Web应用时,认证(Authentication)和授权(Authorization)是两个核心安全机制:
- 认证解决"用户是谁"的问题,验证用户身份的真实性
- 授权解决"用户能做什么"的问题,控制用户对资源的访问权限
FoalTS框架提供了灵活强大的工具来实现这两种机制,支持多种应用场景和架构。
FoalTS认证架构概述
FoalTS的认证系统设计精妙,具有以下特点:
- 多场景支持:无论是传统Web应用、SPA+API还是移动应用+API架构
- 状态管理灵活:支持有状态(Session)和无状态(JWT)两种方式
- 多种凭证类型:支持密码、社交登录等多种认证方式
- 令牌存储多样:支持Cookie、localStorage等多种存储方式
认证流程通常分为两个阶段:
-
登录阶段:
- 验证用户凭证
- 生成认证令牌
- 将令牌返回客户端
-
持续认证阶段:
- 验证后续请求中的令牌
- 获取关联用户信息
令牌类型选择
FoalTS提供两种主要令牌机制:
1. 会话令牌(Session Tokens)
特点:
- 有状态管理
- 自动处理过期
- 易于撤销
- 代码简洁
- 不仅限于传统Web应用,也可用于API架构
2. JWT令牌(JSON Web Tokens)
特点:
- 无状态
- 适合高级开发场景
- 支持社交登录集成
- 需要自行处理令牌续期
实战示例
下面通过具体代码示例展示如何在FoalTS中实现认证系统。我们假设构建一个产品API,用户认证后可访问GET /api/products
。
基础用户实体
首先定义用户实体,这是所有示例的基础:
import { BaseEntity, Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
@Entity()
export class User extends BaseEntity {
@PrimaryGeneratedColumn()
id: number;
@Column({ unique: true })
email: string;
@Column()
password: string;
}
// 使用TypeORM会话时必须导出
export { DatabaseSession } from '@foal/typeorm';
场景1:SPA/移动应用(Cookie方式)
使用会话令牌
- 确保导出
DatabaseSession
实体 - 创建并运行迁移
npm run makemigrations
npm run migrations
App控制器配置:
@UseSessions({
cookie: true,
user: fetchUser(User)
})
export class AppController implements IAppController {
@dependency
store: Store;
subControllers = [
controller('/auth', AuthController),
controller('/api', ApiController),
];
async init() {
await createConnection();
}
}
认证控制器实现:
export class AuthController {
@Post('/signup')
async signup(ctx: Context<any, Session>) {
// 用户创建逻辑
ctx.session.setUser(user);
return new HttpResponseOK();
}
@Post('/login')
async login(ctx: Context<any, Session>) {
// 验证逻辑
ctx.session.setUser(user);
return new HttpResponseOK();
}
@Post('/logout')
async logout(ctx: Context<any, Session>) {
await ctx.session.destroy();
return new HttpResponseOK();
}
}
API控制器保护:
@UserRequired()
export class ApiController {
@Get('/products')
readProducts() {
return new HttpResponseOK([]);
}
}
使用JWT令牌
- 生成并配置JWT密钥
- 设置环境变量
认证控制器差异:
export class AuthController {
private async createJWT(user: User): Promise<string> {
const payload = { email: user.email, id: user.id };
return promisify(sign as any)(
payload,
process.env.JWT_SECRET,
{ subject: user.id.toString() }
);
}
}
场景2:SPA/移动应用(Authorization头方式)
使用会话令牌
认证控制器关键变化:
ctx.session = await createSession(this.store);
ctx.session.setUser(user);
return new HttpResponseOK({
token: ctx.session.getToken()
});
使用JWT令牌
主要区别在于令牌返回方式:
return new HttpResponseOK({
token: await this.createJWT(user)
});
最佳实践建议
- 根据应用场景选择合适的认证方式
- API优先考虑JWT,传统Web应用考虑Session
- 生产环境务必保护JWT密钥
- 考虑添加CSRF保护(使用Cookie时)
- 跨域场景配置CORS
- 密码存储始终使用哈希
通过以上示例和说明,开发者可以快速在FoalTS项目中实现健壮的认证系统,根据实际需求选择合适的认证策略。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考