通过 Angular 4 将 JWT 令牌附加到 api 请求

Posted

技术标签:

【中文标题】通过 Angular 4 将 JWT 令牌附加到 api 请求【英文标题】:attach a JWT token to api request via angular 4 【发布时间】:2018-04-09 02:24:42 【问题描述】:

我正在构建一个带有 ASP.NET Core 2.0 后端的 Angular 应用程序。我已经成功实现了 JWT 登录,它工作正常。现在,按照位于here 的教程,我正在尝试获取需要通过 JWT 授权的资源的数据。当我使用令牌获取 HTTP 时,我使用邮递员验证这是否有效。

在我的 Angular 应用程序中,我收到 401。我将 Visual Studio 2017 Angular 模板应用程序用于我的示例应用程序。其他一切正常,我可以登录,当我的令牌过期时,我被要求再次登录,以便所有这些方面都能正常工作。我只是错过了最后一部分。 服务端api调用如下:

[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[Route("api/[controller]")]
public class SampleDataController : Controller

    private static string[] Summaries = new[]
    
        "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
    ;

    [HttpGet("[action]")]
    public IEnumerable<WeatherForecast> WeatherForecasts()
    
        var rng = new Random();
        return Enumerable.Range(1, 5).Select(index => new WeatherForecast
        
            DateFormatted = DateTime.Now.AddDays(index).ToString("d"),
            TemperatureC = rng.Next(-20, 55),
            Summary = Summaries[rng.Next(Summaries.Length)]
        );
    

    public class WeatherForecast
    
        public string DateFormatted  get; set; 
        public int TemperatureC  get; set; 
        public string Summary  get; set; 

        public int TemperatureF
        
            get
            
                return 32 + (int)(TemperatureC / 0.5556);
            
        
    

角度组件有如下代码:

    import  Component, Inject  from '@angular/core';
import  Http  from '@angular/http';

@Component(
    selector: 'fetchdata',
    templateUrl: './fetchdata.component.html'
)
export class FetchDataComponent 
    public forecasts: WeatherForecast[];

    constructor(http: Http, @Inject('BASE_URL') baseUrl: string) 
        http.get(baseUrl + 'api/SampleData/WeatherForecasts').subscribe(result => 
            this.forecasts = result.json() as WeatherForecast[];
        , error => console.error(error));
    


interface WeatherForecast 
    dateFormatted: string;
    temperatureC: number;
    temperatureF: number;
    summary: string;

这是添加授权标头的代码:

    import  Injectable  from '@angular/core';

import 
  HttpRequest,
  HttpHandler,
  HttpEvent,
  HttpInterceptor from '@angular/common/http';
//import  AuthService  from './auth/auth.service';
import  Observable  from 'rxjs/Observable';
import  Http  from "@angular/http/http";
import  AuthService  from "./auth.service";
import  HttpClient  from "@angular/common/http";
@Injectable()
export class TokenInterceptor implements HttpInterceptor 
  constructor(public auth: AuthService)  
  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> 

    request = request.clone(
      setHeaders: 
        Authorization: `Bearer $this.auth.getToken()`
      
    );
    return next.handle(request);
  

我们将不胜感激。

【问题讨论】:

【参考方案1】:

问题出在这里:

   Authorization: `Bearer $this.auth.getToken()`

getToken 方法正在返回整个 Token 对象。相反,正如有人在另一个线程上指出的那样,我必须显式提取实际的令牌字符串,如下所示:

JSON.parse(localStorage.getItem('token')).token

这解决了我的问题。

【讨论】:

【参考方案2】:

您可以将选项参数传递给您的 http get 方法,请查看此处 https://angular.io/api/http/RequestOptionsArgs

【讨论】:

【参考方案3】:

所以这个很简单,你发的教程用的是angualar-jwt(我自己用过)。

他们为 http 服务提供自己的包装器,该服务将保存的 JWT 令牌作为请求的一部分发送到您(或其他人的)API 端点。

如果是其他人的 API,请确保您更改标头前缀以匹配他们期望 JWT 令牌的位置。

来自 angular2-jwt 自述文件:

如果您希望仅针对特定 HTTP 请求发送 JWT,则可以使用 AuthHttp 类。此类是 Angular 2 的 Http 的包装器,因此支持所有相同的 HTTP 方法。

import  AuthHttp  from 'angular2-jwt';
// ...
class App 

thing: string;

constructor(public authHttp: AuthHttp) 

getThing() 
    this.authHttp.get('http://example.com/api/thing')
    .subscribe(
        data => this.thing = data,
        err => console.log(err),
        () => console.log('Request Complete')
    );


【讨论】:

嗨,如果你看一下教程,他们有一个 Ping 组件,它使用新的 HttpClient 类来获取数据。因此,这应该可以在不使用您的方法的情况下工作 我已经更新了拦截器代码的问题。它会自动将任何令牌附加到授权标头,因此不需要额外的工作

以上是关于通过 Angular 4 将 JWT 令牌附加到 api 请求的主要内容,如果未能解决你的问题,请参考以下文章

防止在 Angular 中多次触发令牌刷新请求

JWT 和防伪令牌

如何从 django rest 框架访问 jwt 令牌到 Angular 前端

如何将 JWT 令牌从 PHP 发送到 Angular?

如何将我的 JWT 令牌附加到每个 axios 调用?

如何将一些附加字段添加到此 Spring Boot 服务生成的 JWT 令牌中?