You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 10升级到Angular 13后项目授权功能异常问题求助

修复步骤

1. 修复类型不匹配与空值解析异常

Angular 13配套的TypeScript版本类型检查更严格,原有代码的类型声明和空值处理会直接触发报错:

  • 修改TokenStorage的getToken返回类型,兼容sessionStorage返回null的场景:
public getToken(): string | null {
    return sessionStorage.getItem(TOKEN_KEY);
}
  • 优化getAuthority方法的空值判断和JSON解析异常捕获,避免授权信息为空时直接崩溃:
public getAuthority(): string[] {
    this.roles = []
    const token = this.getToken();
    const authStr = sessionStorage.getItem(AUTHORITIES_KEY);
    if (token && authStr) {
      try {
        const authorities = JSON.parse(authStr);
        authorities.forEach(authority => {
          this.roles.push(authority.authority);
        });
      } catch(e) {
        // 解析失败直接清空登录状态
        this.signOut();
      }
    }
    return this.roles;
}

2. 兼容RxJS 7+的语法变更

Angular 13默认使用RxJS 7以上版本,原有throwError传值的写法已废弃,需要改为传入工厂函数:

  • 调整AuthService中login和register的错误处理逻辑,同时修正login方法中console.log在return后无法执行的问题:
login(login: string, password: string): Observable<any> {
    const credentials = {login: login, password: password};
    return this._http.post<any>(this.watkrewUrl + "signin", credentials).pipe(
      catchError((err: HttpErrorResponse) => {
        console.log(err.message)
        return throwError(() => err.error.message);
      }
    ))
}

register(login: string, password: string, email: string, name: string, surname: string, role: string): Observable<any>{
    const signupForm = {login: login, password: password, email:email, name:name, surname: surname, role: role}
    return this._http.post<any>(this.watkrewUrl + "signup", signupForm).pipe(
      catchError((err: HttpErrorResponse)=> {
        return throwError(() => err.error.message);
      })
    )
}

3. 完善拦截器逻辑与注册配置

  • 先确认AppModule的providers数组中已正确注册拦截器和相关服务:
import { HTTP_INTERCEPTORS } from '@angular/common/http';
// 其余导入省略

providers: [
  { provide: HTTP_INTERCEPTORS, useClass: Interceptor, multi: true },
  TokenStorage,
  AuthService
]
  • 补充拦截器401状态的处理逻辑,避免授权失效后依旧保留登录状态:
return next.handle(authReq).pipe( tap(() => {},
  (err: any) => {
    if (err instanceof HttpErrorResponse && err.status === 401) {
      this.token.signOut();
      this.router.navigate(['/login']); // 替换为实际的登录页路由
    }
  }
));

4. 补充服务的根作用域声明

给TokenStorage和AuthService补充providedIn配置,避免模块注册遗漏导致的注入异常:

@Injectable({
  providedIn: 'root'
})
export class TokenStorage {
  // 原有逻辑不变
}

@Injectable({
  providedIn: 'root'
})
export class AuthService {
  // 原有逻辑不变
}

5. 可选:跨域请求配置

如果后端服务和前端地址端口不一致,在拦截器克隆请求时补充withCredentials配置:

authReq = req.clone({ 
  headers: req.headers.set(TOKEN_HEADER_KEY, 'Bearer ' + this.token.getToken()),
  withCredentials: true 
});

内容的提问来源于stack exchange,提问作者giluwilu7

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 12:06:03