范围:src/gateway/auth/, src/business/auth/, src/app.module.ts 涉及文件: - 新增:src/gateway/auth/ 目录及所有文件 - 移动:Controller、Guard、Decorator、DTO从business层移至gateway层 - 修改:src/business/auth/index.ts(移除Gateway层组件导出) - 修改:src/app.module.ts(使用AuthGatewayModule替代AuthModule) 主要改进: - 明确Gateway层和Business层的职责边界 - Controller、Guard、Decorator属于Gateway层职责 - Business层专注于业务逻辑和服务 - 符合分层架构设计原则
150 lines
3.8 KiB
TypeScript
150 lines
3.8 KiB
TypeScript
/**
|
||
* JWT 使用示例
|
||
*
|
||
* 架构层级:Gateway Layer(网关层)
|
||
*
|
||
* 功能描述:
|
||
* - 展示如何在控制器中使用 JWT 认证守卫和当前用户装饰器
|
||
* - 提供完整的JWT认证使用示例和最佳实践
|
||
* - 演示不同场景下的认证和授权处理
|
||
*
|
||
* 职责分离:
|
||
* - 专注于JWT认证功能的使用演示
|
||
* - 提供开发者参考的代码示例
|
||
* - 展示认证守卫和装饰器的最佳实践
|
||
*
|
||
* 架构说明:
|
||
* - 本文件位于Gateway层,符合Controller的架构定位
|
||
* - JWT Guard和装饰器位于同层(src/gateway/auth)
|
||
* - 本文件作为使用示例参考
|
||
*
|
||
* 最近修改:
|
||
* - 2026-01-14: 架构优化 - 将文件从Business层移至Gateway层,符合架构分层原则 (Modified by: moyin)
|
||
* - 2026-01-14: 代码规范优化 - 修正导入路径,指向Gateway层 (Modified by: moyin)
|
||
* - 2026-01-07: 代码规范优化 - 文件夹扁平化,移除单文件文件夹结构
|
||
*
|
||
* @author moyin
|
||
* @version 1.2.0
|
||
* @since 2025-01-05
|
||
* @lastModified 2026-01-14
|
||
*/
|
||
|
||
import { Controller, Get, UseGuards, Post, Body } from '@nestjs/common';
|
||
import { JwtAuthGuard } from './jwt_auth.guard';
|
||
import { JwtPayload } from '../../core/login_core/login_core.service';
|
||
import { CurrentUser } from './current_user.decorator';
|
||
|
||
/**
|
||
* 示例控制器 - 展示 JWT 认证的使用方法
|
||
*/
|
||
@Controller('example')
|
||
export class ExampleController {
|
||
|
||
/**
|
||
* 公开接口 - 无需认证
|
||
*/
|
||
@Get('public')
|
||
getPublicData() {
|
||
return {
|
||
message: '这是一个公开接口,无需认证',
|
||
timestamp: new Date().toISOString(),
|
||
};
|
||
}
|
||
|
||
/**
|
||
* 受保护的接口 - 需要 JWT 认证
|
||
*
|
||
* 请求头示例:
|
||
* Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
||
*/
|
||
@Get('protected')
|
||
@UseGuards(JwtAuthGuard)
|
||
getProtectedData(@CurrentUser() user: JwtPayload) {
|
||
return {
|
||
message: '这是一个受保护的接口,需要有效的 JWT 令牌',
|
||
user: {
|
||
id: user.sub,
|
||
username: user.username,
|
||
role: user.role,
|
||
},
|
||
timestamp: new Date().toISOString(),
|
||
};
|
||
}
|
||
|
||
/**
|
||
* 获取当前用户信息
|
||
*/
|
||
@Get('profile')
|
||
@UseGuards(JwtAuthGuard)
|
||
getUserProfile(@CurrentUser() user: JwtPayload) {
|
||
return {
|
||
profile: {
|
||
userId: user.sub,
|
||
username: user.username,
|
||
role: user.role,
|
||
tokenIssuedAt: new Date(user.iat * 1000).toISOString(),
|
||
tokenExpiresAt: new Date(user.exp * 1000).toISOString(),
|
||
},
|
||
};
|
||
}
|
||
|
||
/**
|
||
* 获取用户的特定属性
|
||
*/
|
||
@Get('username')
|
||
@UseGuards(JwtAuthGuard)
|
||
getUsername(@CurrentUser('username') username: string) {
|
||
return {
|
||
username,
|
||
message: `你好,${username}!`,
|
||
};
|
||
}
|
||
|
||
/**
|
||
* 需要特定角色的接口
|
||
*/
|
||
@Post('admin-only')
|
||
@UseGuards(JwtAuthGuard)
|
||
adminOnlyAction(@CurrentUser() user: JwtPayload, @Body() data: any) {
|
||
// 检查用户角色
|
||
if (user.role !== 1) { // 假设 1 是管理员角色
|
||
return {
|
||
success: false,
|
||
message: '权限不足,仅管理员可访问',
|
||
};
|
||
}
|
||
|
||
return {
|
||
success: true,
|
||
message: '管理员操作执行成功',
|
||
data,
|
||
operator: user.username,
|
||
};
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 使用说明:
|
||
*
|
||
* 1. 首先调用登录接口获取 JWT 令牌:
|
||
* POST /auth/login
|
||
* {
|
||
* "identifier": "username",
|
||
* "password": "password"
|
||
* }
|
||
*
|
||
* 2. 从响应中获取 access_token
|
||
*
|
||
* 3. 在后续请求中添加 Authorization 头:
|
||
* Authorization: Bearer <access_token>
|
||
*
|
||
* 4. 访问受保护的接口:
|
||
* GET /example/protected
|
||
* GET /example/profile
|
||
* GET /example/username
|
||
* POST /example/admin-only
|
||
*
|
||
* 错误处理:
|
||
* - 401 Unauthorized: 令牌缺失或无效
|
||
* - 403 Forbidden: 令牌有效但权限不足
|
||
*/ |