代码之家  ›  专栏  ›  技术社区  ›  Jacob Goh

如何使用httpinterceptor中的ngxs存储值?

  •  1
  • Jacob Goh  · 技术社区  · 6 年前

    我对棱角很陌生。我使用Angular6和NGXS进行状态管理。

    我的NGXS商店有一个 user 接口为

    /* src/app/store/models/user.model.ts */
    export interface User {
        serverToken? : string;
        // and other unrelated stuff
    }
    

    我想用 serverToken 在里面 Authorization A中的标题 HttpInterceptor .

    这是我的电流 高温拦截器 代码

    import {Store, Select} from '@ngxs/store';
    import {Injectable} from '@angular/core';
    import {HttpInterceptor, HttpHandler, HttpRequest, HttpEvent} from '@angular/common/http';
    
    import {Observable} from 'rxjs';
    import {User} from '../store/models/user.model';
    
    @Injectable()
    export class ApiInterceptor implements HttpInterceptor {
        constructor(private store : Store) {}
        @Select()user$ : Observable < User >;
    
        intercept(req : HttpRequest < any >, next : HttpHandler) : Observable < HttpEvent < any >> {
            let options = {
                url: `https://base-url.com/api/${req.url}`
            };
    
            const serverToken = '???';
            if (serverToken) // if not empty
                options = {
                    ...options,
                    headers: req
                        .headers
                        .set('Authorization', `JWT ${serverToken}`)
                }
    
            const duplicate = req.clone(options);
    
            return next.handle(duplicate);
        }
    }
    

    所以我的问题是: 如何正确优雅地使用 user$ 可观察得到 服务器令牌 用在 高温拦截器 如果 服务器令牌 不是空的吗?

    2 回复  |  直到 6 年前
        1
  •  3
  •   kctang    6 年前

    如果您更喜欢“可观察”的方法,请尝试以下方法:

    intercept(req : HttpRequest < any >, next : HttpHandler) : Observable < HttpEvent < any >> {
    
      return this.serverToken$.pipe(
        take(1),
        concatMap(serverToken => {
          if (serverToken) {
            options = {
              ...options,
              headers: req
                .headers
                .set('Authorization', `JWT ${serverToken}`)
            }
            const duplicate = req.clone(options);
            return next.handle(duplicate)
          } else {
            // next() without changing req
            return next(req)
          }
        }
      )
    }
    

    您还需要定义 @Selector 返回用户令牌和 @Select 它来自拦截器类。

    注意:我不熟悉HTTP拦截器,只是根据我在签名中看到的内容应用了链接RXJS可观测数据的概念。 intercept() .

        2
  •  1
  •   Jacob Goh    6 年前

    我最终使用了 snapshot NGXS的特点。不确定这是不是最好的方法。(快照功能在NGXS中可用,但在NGRX中不可用。我不知道如何在NGRX中解决这个问题)

    在user.state.ts中

    @State < User > ({name: "user", defaults: {}})
    export class UserState {
        // ... 
    
        @Selector()
        static serverToken(user : User) {
            return user.serverToken || '';
        }
    }
    

    在里面 HttpInterceptor

        const serverToken = this
            .store
            .selectSnapshot(UserState.serverToken);