Нет описания
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

auth.service.ts 4.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. import { Injectable, inject } from '@angular/core';
  2. import { HttpClient } from '@angular/common/http';
  3. import { Observable, BehaviorSubject, throwError } from 'rxjs';
  4. import { tap, catchError } from 'rxjs/operators';
  5. import { Router } from '@angular/router';
  6. import { LoginRequest, LoginResponse, UserInfo, AuthState } from '../models/auth.model';
  7. @Injectable({
  8. providedIn: 'root'
  9. })
  10. export class AuthService {
  11. private http = inject(HttpClient);
  12. private router = inject(Router);
  13. private authState = new BehaviorSubject<AuthState>({
  14. isAuthenticated: false
  15. });
  16. authState$ = this.authState.asObservable();
  17. private readonly TOKEN_KEY = 'auth_token';
  18. private readonly USER_KEY = 'auth_user';
  19. constructor() {
  20. console.log('AuthService初始化 (Token认证)');
  21. this.initializeAuthState();
  22. }
  23. private initializeAuthState() {
  24. console.log('初始化认证状态');
  25. const token = this.getToken();
  26. const user = this.getUser();
  27. console.log('本地存储Token:', token ? '有' : '无');
  28. console.log('本地存储用户:', user);
  29. // 从本地存储恢复认证状态
  30. if (token && user) {
  31. console.log('从本地存储恢复认证状态');
  32. this.authState.next({
  33. isAuthenticated: true,
  34. token,
  35. user
  36. });
  37. } else {
  38. console.log('未找到保存的认证信息,需要重新登录');
  39. // 清除可能的不完整数据
  40. if (token || user) {
  41. console.log('清除不完整的认证数据');
  42. this.clearAuthData();
  43. }
  44. // 初始状态设置为未认证
  45. this.authState.next({
  46. isAuthenticated: false
  47. });
  48. }
  49. }
  50. login(username: string, password: string): Observable<LoginResponse> {
  51. console.log('开始登录,用户名:', username);
  52. // 调用svc-code登录API
  53. const apiUrl = '/api/auth/login';
  54. console.log('登录API:', apiUrl);
  55. const loginData: LoginRequest = {
  56. user_id: username,
  57. password: password
  58. };
  59. return this.http.post<LoginResponse>(apiUrl, loginData).pipe(
  60. tap(response => {
  61. console.log('登录响应:', response);
  62. if (response.success && response.data) {
  63. // 登录成功,保存token和用户信息
  64. const token = response.data;
  65. console.log('获取到Token:', token);
  66. this.setToken(token);
  67. // 创建用户信息(后续可以从验证端点获取详细信息)
  68. const userInfo: UserInfo = {
  69. user_id: username,
  70. username: username,
  71. authenticated: true
  72. };
  73. this.setUser(userInfo);
  74. this.authState.next({
  75. isAuthenticated: true,
  76. token,
  77. user: userInfo
  78. });
  79. console.log('登录成功,认证状态更新');
  80. } else {
  81. console.warn('登录失败:', response.message || response.error);
  82. throw new Error(response.message || response.error || '登录失败');
  83. }
  84. }),
  85. catchError(error => {
  86. console.error('登录失败:', error);
  87. return throwError(() => error);
  88. })
  89. );
  90. }
  91. logout() {
  92. console.log('用户登出');
  93. this.clearAuthData();
  94. this.authState.next({
  95. isAuthenticated: false
  96. });
  97. this.router.navigate(['/login']);
  98. }
  99. isAuthenticated(): boolean {
  100. return this.authState.value.isAuthenticated;
  101. }
  102. getToken(): string | null {
  103. // 优先使用内存中的token,保持一致性
  104. if (this.authState.value.token) {
  105. return this.authState.value.token;
  106. }
  107. // 回退到localStorage
  108. return localStorage.getItem(this.TOKEN_KEY);
  109. }
  110. private setToken(token: string) {
  111. localStorage.setItem(this.TOKEN_KEY, token);
  112. }
  113. private setUser(user: UserInfo) {
  114. if (user) {
  115. localStorage.setItem(this.USER_KEY, JSON.stringify(user));
  116. }
  117. }
  118. private getUser(): UserInfo | null {
  119. const userStr = localStorage.getItem(this.USER_KEY);
  120. if (userStr) {
  121. try {
  122. return JSON.parse(userStr);
  123. } catch (e) {
  124. console.error('解析用户信息失败:', e);
  125. return null;
  126. }
  127. }
  128. return null;
  129. }
  130. private clearAuthData() {
  131. localStorage.removeItem(this.TOKEN_KEY);
  132. localStorage.removeItem(this.USER_KEY);
  133. }
  134. // 获取当前用户信息
  135. getCurrentUser(): UserInfo | undefined {
  136. return this.authState.value.user;
  137. }
  138. // 获取当前token(用于API调用)
  139. getAuthToken(): string | null {
  140. return this.getToken();
  141. }
  142. // 验证token有效性(可选,调用验证端点)
  143. validateToken(): Observable<any> {
  144. const apiUrl = '/api/auth/validate';
  145. return this.http.post(apiUrl, {});
  146. }
  147. }