Angular 中的不记名令牌

Posted

技术标签:

【中文标题】Angular 中的不记名令牌【英文标题】:Bearer token in Angular 【发布时间】:2018-11-08 10:33:14 【问题描述】:

我正在构建使用 OAuth 授权的 Web 应用程序。要访问数据,我需要向端点询问令牌并将其放在授权标头中。

我在 Angular 中制作了拦截器,它为 API 调用放置了正确的标头,并且该部分工作正常。

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> 
    if(!(req.headers.get("Content-Type") === "application/x-www-form-urlencoded")) 

      const authReq = req.clone(
        headers: req.headers.set('Authorazation', 'Bearer ' + this.callToken()
          .then(resp => resp)
          .catch(err => console.log(err)))
      );
      return next.handle(authReq)
    else 
      return next.handle(req);
    
  

但是我有这个方法 callToken() 我使用 Promis 来调用令牌。 现在这个方法返回承诺我不能把它放在正确类型的标题中它总是看起来像

      callToken(): Promise<any> 
    let url = 'url';
    let body = "body";
    let promise = fetch(url, 
      body: body,
      headers: 
        'Content-Type': 'application/x-www-form-urlencoded'
      ,
      method: 'POST',
    );

    return promise
      .then(resp => resp.json())
      .then(json => json.access_token);

  

有趣的是,当我说 resp => 时,console.log(resp.acces_token) 令牌打印得很漂亮。

我也尝试使用回调

      callForToken(): string 
    let url = 'url';
    let body = 'body';

    let option = 
      headers: new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded')
    ;
    let token;
    this.http.post<Token>(url, body, option).subscribe(
      res => 
        token = res.access_token;
      
    );
    return token;
  

但由于异步调用,我无法访问方法之外的令牌数据

【问题讨论】:

所以您要拦截每个 API 调用以首先进行 API 调用以获取访问令牌?这似乎非常低效。您应该在“登录”到您的应用程序时获取您的访问令牌并将其存储在某个地方,例如 LocalStorage 或创建一个 AuthService,然后在您的拦截器中使用它,而不是每次发出另一个请求时都调用您的访问令牌. 每个令牌在过期前都存在 5 分钟。该解决方案是出于安全目的而制作的。如果我能正确获得令牌,我将做出该声明以首先检查令牌是否已过期,如果是,则调用新的 你有没有试过让那个拦截async函数然后await this.callToken() 当我尝试使拦截方法异步时,在 src/app/auth.interceptor.ts(18,62) 中出现错误错误:错误 TS1055:类型“typeof Observable”不是有效的异步函数ES5/ES3 中的返回类型,因为它不引用与 Promise 兼容的构造函数值。 src/app/auth.interceptor.ts(18,62): error TS1055: Type 'typeof Observable' 在 ES5/ES3 中不是有效的异步函数返回类型,因为它没有引用与 Promise 兼容的构造函数值。 'subscribe' 和 'executor' 的参数类型不兼容。 【参考方案1】:

我仍然试图找到解决方案。 现在我结束了

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> 
    if (!(req.headers.get('Content-Type') === 'application/x-www-form-urlencoded')) 
      return Observable.fromPromise(this.handleAccess(req, next));
    
  


  private async handleAccess(req: HttpRequest<any>, next: HttpHandler): Promise<HttpEvent<any>> 
    const token = await this.callToken();
    console.log(token);

    let changeRequest;

    if (token) 
      changeRequest = req.clone(
        headers: req.headers.set('Authorization', 'Bearer ' + token)
      );
    

    return next.handle(changeRequest).toPromise();
  

  callToken(): Promise<Token> 
    let url = 'url';
    let body = 'body';


    return fetch(url, 
      body: body,
      headers: 
        'Content-Type': 'application/x-www-form-urlencoded'
      ,
      method: 'POST',
    ).then(resp => resp.json())
      .then(json => json.acces_token)
      .catch(err => console.error(err));


  

但令牌仍然未定义

编辑:实际上这是工作。我搞砸了 URL 和正文

【讨论】:

以上是关于Angular 中的不记名令牌的主要内容,如果未能解决你的问题,请参考以下文章

授权不记名令牌Angular 5

不记名令牌未添加到 HTTP 请求 - MSAL2 Angular

如何更改 Moya 中的不记名令牌

OAuth 2 中的不记名令牌和 token_type 是啥?

邮递员中的不记名令牌

Angular JWT 令牌