【问题标题】:JWT interceptor removing contentype headerJWT 拦截器删除内容类型标头
【发布时间】:2019-02-21 00:28:44
【问题描述】:

我面临无法使用 JWT 拦截器进行 api 调用的问题。我得到了:

不支持内容类型“text/plain;charset=UTF-8”

我猜是因为 JWT 拦截器正在删除标头并添加 Bearer 的东西,这是我的 JWT 拦截器。

import { Injectable } from "@angular/core";
import {
  HttpRequest,
  HttpHandler,
  HttpEvent,
  HttpInterceptor
} from "@angular/common/http";
import { Observable } from "rxjs";

@Injectable()
export class JwtInterceptor implements HttpInterceptor {
  intercept(
    request: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    // add authorization header with jwt token if available
    let credentials = JSON.parse(localStorage.getItem("credentials"));
    console.log(JSON.stringify(credentials.accessToken));
    if (credentials && credentials.accessToken) {
      request = request.clone({
        setHeaders: {
          Authorization: `Bearer ${credentials.accessToken}`
        }
      });
    }

    return next.handle(request);
  }

}

我尝试使用邮递员,如果我不理会这个标题,它会说同样的问题,但是当我添加 Content-Type application/json 它解决了问题,但是在 Angular 中我如何添加这个标题但是代替?

【问题讨论】:

  • 添加application/jsonContent-Type 有什么问题? setHeaders() 完全替换所有标题。您是否在问如何添加/设置 authorization 标头并保留请求中的所有其他标头?

标签: angular typescript angular6


【解决方案1】:

理论上,您应该能够像添加 Authorization 标头一样添加标头:

    if (credentials && credentials.accessToken) {
      request = request.clone({
        setHeaders: {
          Authorization: `Bearer ${credentials.accessToken}`,
          "Content-Type": "application/json"
        }
      });
    }

或者,您可能想要检查请求的发起者,以验证它不是首先设置错误标头的发起者。

查看 Angular 源代码 (https://github.com/angular/angular/blob/f8096d499324cf0961f092944bbaedd05364eea1/packages/common/http/src/request.ts#L369) setHeaders 似乎添加或更新任何现有的标头,保留您未提及的任何标头:

    if (update.setHeaders !== undefined) {
      // Set every requested header.
      headers =
          Object.keys(update.setHeaders)
              .reduce((headers, name) => headers.set(name, update.setHeaders ![name]), headers);
    }

【讨论】:

    【解决方案2】:

    如果目标是在保留现有标头的同时添加授权标头,在本例中为 content-type,您可以使用 request.headers.set() 而不是 setHeaders(),因为 setHeaders() 完全替换了标头:

    import { Injectable } from "@angular/core";
    import {
      HttpRequest,
      HttpHandler,
      HttpEvent,
      HttpInterceptor
    } from "@angular/common/http";
    import { Observable } from "rxjs";
    
    @Injectable()
    export class JwtInterceptor implements HttpInterceptor {
      intercept(
        request: HttpRequest<any>,
        next: HttpHandler
      ): Observable<HttpEvent<any>> {
        // add authorization header with jwt token if available
        let credentials = JSON.parse(localStorage.getItem("credentials"));
        console.log(JSON.stringify(credentials.accessToken));
        if (credentials && credentials.accessToken) {
          request = request.clone({
            headers: request.headers.set('Authorization', `Bearer ${credentials.accessToken}`)
          });
        }
    
        return next.handle(request);
      }
    }
    

    希望对您有所帮助!

    【讨论】:

      猜你喜欢
      • 2020-09-08
      • 2020-08-14
      • 1970-01-01
      • 1970-01-01
      • 2018-02-14
      • 1970-01-01
      • 1970-01-01
      • 2019-07-07
      • 1970-01-01
      相关资源
      最近更新 更多