2
0

auth.service.ts 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. import jwt from 'jsonwebtoken';
  2. import { UserService } from '../users/user.service';
  3. import { UserEntity as User } from '../users/user.entity';
  4. import { DisabledStatus } from '@/share/types';
  5. import debug from 'debug';
  6. const logger = {
  7. info: debug('backend:auth:info'),
  8. error: debug('backend:auth:error')
  9. }
  10. const JWT_SECRET = 'your-secret-key'; // 生产环境应使用环境变量
  11. const JWT_EXPIRES_IN = '7d'; // 7天有效期
  12. const ADMIN_USERNAME = 'admin';
  13. const ADMIN_PASSWORD = 'admin123';
  14. export class AuthService {
  15. private userService: UserService;
  16. constructor(userService: UserService) {
  17. this.userService = userService;
  18. }
  19. async ensureAdminExists(): Promise<User> {
  20. try {
  21. let admin = await this.userService.getUserByUsername(ADMIN_USERNAME);
  22. if (!admin) {
  23. logger.info('Admin user not found, creating default admin account');
  24. admin = await this.userService.createUser({
  25. username: ADMIN_USERNAME,
  26. password: ADMIN_PASSWORD,
  27. nickname: '系统管理员',
  28. isDisabled: DisabledStatus.ENABLED
  29. });
  30. logger.info('Default admin account created successfully');
  31. }
  32. return admin;
  33. } catch (error) {
  34. logger.error('Failed to ensure admin account exists:', error);
  35. throw error;
  36. }
  37. }
  38. async login(username: string, password: string): Promise<{ token: string; user: User }> {
  39. try {
  40. // 确保admin用户存在
  41. if (username === ADMIN_USERNAME) {
  42. await this.ensureAdminExists();
  43. }
  44. const user = await this.userService.getUserByUsername(username);
  45. if (!user) {
  46. throw new Error('User not found');
  47. }
  48. // 检查用户是否被禁用
  49. if (user.isDisabled === DisabledStatus.DISABLED) {
  50. throw new Error('User account is disabled');
  51. }
  52. const isPasswordValid = await this.userService.verifyPassword(user, password);
  53. if (!isPasswordValid) {
  54. throw new Error('Invalid password');
  55. }
  56. const token = this.generateToken(user);
  57. return { token, user };
  58. } catch (error) {
  59. logger.error('Login error:', error);
  60. throw error;
  61. }
  62. }
  63. generateToken(user: User, expiresIn?: string | number): string {
  64. const payload = {
  65. id: user.id,
  66. username: user.username,
  67. roles: user.roles?.map(role => role.name) || []
  68. };
  69. const options = expiresIn ? { expiresIn } : { expiresIn: JWT_EXPIRES_IN };
  70. return jwt.sign(payload, JWT_SECRET, options as jwt.SignOptions);
  71. }
  72. verifyToken(token: string): any {
  73. try {
  74. return jwt.verify(token, JWT_SECRET);
  75. } catch (error) {
  76. console.error('Token verification failed:', error);
  77. throw new Error('Invalid token');
  78. }
  79. }
  80. async logout(token: string): Promise<void> {
  81. try {
  82. // 验证token有效性
  83. const decoded = this.verifyToken(token);
  84. if (!decoded) {
  85. throw new Error('Invalid token');
  86. }
  87. // 实际项目中这里可以添加token黑名单逻辑
  88. // 或者调用Redis等缓存服务使token失效
  89. return Promise.resolve();
  90. } catch (error) {
  91. console.error('Logout failed:', error);
  92. throw error;
  93. }
  94. }
  95. }