【问题标题】:Angular JWT: Authorization Header is null?Angular JWT:授权标头为空?
【发布时间】:2020-07-26 02:27:30
【问题描述】:

tutorial 之后,我想在我的 Angular 应用程序中实现一个登录功能,该功能与 Spring Boot 中的后端通信,并且在后端使用 Spring 安全性。

问题很明显:在我的程序中,授权标头没有正确添加

在我的 jwt.interceptor.ts 中,我包含了一些 conole.log 命令来查看问题所在:

@Injectable()
export class JwtInterceptor implements HttpInterceptor {

  constructor(private authenticationService: AuthenticationService) {}

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    let currentUser = this.authenticationService.currentUserValue;
    console.log(currentUser);
    console.log(request.headers);
    if (currentUser) {
      // token exists on user so we take the request and add an Authorization header with the jwt token so we keep access
      request = request.clone({
        setHeaders: {
          Authorization: `Bearer ${currentUser.token}` //basically what I do in postman to get access
        }
      });
    }
    return next.handle(request);
  }
}

当我查看控制台时,奇怪的是实例 currentUser 似乎有一个 jwt-token 作为它的主体,但是当我尝试打印出它的令牌字段(在它的类中定义)时,该字段是未定义的

虽然请求头附加了一个 Authorization 标头,但 Bearer 值是未定义的

在我的授权服务 (authorization.service.ts) 中发生的事情是从本地存储调用具有 key currentUser 的对象并返回其值。这在我们登录时存储 - 我们从 /authenticate 端点 JSON.stringify 获取用户并将其存储在本地存储中。然后在获取 currentUserValue 时,我得到它的 .value 字段:

  constructor(private httpClient: HttpClient) {
    this.currentUserSubject = new BehaviorSubject<User>(JSON.parse(localStorage.getItem('currentUser'))); // user from json
    this.currentUser = this.currentUserSubject.asObservable();
  }

.......

public get currentUserValue(): User {
    return this.currentUserSubject.value;
  }

如何将令牌正确添加到我的授权标头中?

我找到了一个不那么漂亮的解决方案:

在 auhentication.service 的构造函数中执行此操作(并将字段也添加到类中):

  constructor(private httpClient: HttpClient) {
    this.tokenString = new BehaviorSubject<any>(JSON.parse(localStorage.getItem('currentUser'))).value.jwt;
  }

然后在设置授权标头时调用访问该字段。至少这解决了这个问题。如果有更好的解决方案我想知道。

这里有一个更好的解决方案:

首先将一个名为 jwt 的字符串字段添加到您的用户类中,然后在构造函数中执行此操作,因为 currentUser 只能调用一次:

  constructor(private httpClient: HttpClient) {
    this.currentUserSubject = new BehaviorSubject<User>(JSON.parse(localStorage.getItem('currentUser')));
    this.tokenString = this.currentUserSubject.value.jwt;
    this.currentUser = this.currentUserSubject.asObservable();
  }

【问题讨论】:

    标签: angular typescript jwt


    【解决方案1】:

    试试这样 在jwt 键中可用的控制台令牌中,您正在使用token 键访问

    @Injectable()
    export class JwtInterceptor implements HttpInterceptor {
    
      constructor(private authenticationService: AuthenticationService) {}
    
      intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        let currentUser = this.authenticationService.currentUserValue;
        console.log(currentUser);
        console.log(request.headers);
        if (currentUser) {
          // token exists on user so we take the request and add an Authorization header with the jwt token so we keep access
          request = request.clone({
            setHeaders: {
              Authorization: `Bearer ${currentUser.jwt}` //basically what I do in postman to get access
            }
          });
        }
        return next.handle(request);
      }
    }
    

    【讨论】:

    • 这不起作用,因为我的用户类没有名为 jwt 的字段。
    【解决方案2】:

    From the docs 标头的键不是setHeaders 而是headers,所以这是克隆请求的正确方法:

    request = request.clone({
      headers: new HttpHeaders({
        Authorization: `Bearer ${currentUser.token}`
      })
    });
    

    【讨论】:

    • 它实际上是双向的,问题是 currentUser 没有任何字段令牌值。我找到了一个丑陋的解决方法,它似乎有效。
    猜你喜欢
    • 2016-01-22
    • 2015-11-05
    • 2019-09-23
    • 2016-07-15
    • 2018-09-16
    • 1970-01-01
    • 2017-07-01
    • 1970-01-01
    相关资源
    最近更新 更多