在 spartacus 中具有 oauth2 授权的 i18n-backend

i18n-backend with oauth2 authorization in spartacus

我们想在 spartacus 中使用 i18n 后端。不幸的是,此后端需要 oauth2 身份验证,但 spartacus 在尝试访问此 web 服务端点时不发送不记名令牌,我们收到 401 错误。我们可以做些什么吗? 现在我们尝试以这种方式解决这个问题: 我们需要在 ClientTokenInterceptor 中实现,因此我们调整了这个拦截器,稍微更改了 if 子句,使其适合此 Web 服务的后端 url 并通过 app.module.ts 提供拦截器到目前为止工作。不幸的是在我们的拦截器中调用 this.authService.getClientToken() returns 没有令牌。

constructor(
    private authService: AuthService,
    private occEndpoints: OccEndpointsService
  ) {}

  intercept(
    request: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    return this.getClientToken(request).pipe(
      take(1),
      switchMap((token: ClientToken) => {
        if (
          token &&
          request.url.includes("i18n")
        ) {
          request = request.clone({
            setHeaders: {
              Authorization: `${token.token_type} ${token.access_token}`,
            },
          });
        }
        return next.handle(request);
      })
    );
  }

  private getClientToken(request: HttpRequest<any>): Observable<ClientToken> {
    if (
      InterceptorUtil.getInterceptorParam(USE_CLIENT_TOKEN, request.headers)
    ) {
      return this.authService.getClientToken();
    }
    return of(null);
  }

我们错过了什么?

实际上,您的解决方案中有一些不需要的东西。

我在下面粘贴了我所做的并测试它是否正常工作(您可以在翻译文件请求中看到授权数据)。

第一期: InterceptorUtil.getInterceptorParam(USE_CLIENT_TOKEN, request.headers) 你不需要检查那个。如果您总是需要翻译请求的授权数据,只需使用 return this.authService.getClientToken();

第二期: 在 intercept 方法中,除了翻译之外,您没有涵盖任何其他请求的案例。因此,对客户端令牌的请求会挂在这里,因为它会等待令牌等等。如果您为除 i18n 之外的任何其他情况添加选项,它会按您的预期开始工作。

工作解决方案:

@Injectable({ providedIn: 'root' })
export class TranslationsInterceptor implements HttpInterceptor {
  constructor(private authService: AuthService) {}

  intercept(
    request: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    if (request?.url?.includes('i18n')) {
      return this.getClientToken().pipe(
        take(1),
        switchMap((token: ClientToken) => {
          if (token) {
            request = request.clone({
              setHeaders: {
                Authorization: `${token.token_type} ${token.access_token}`,
              },
            });
          }
          return next.handle(request);
        })
      );
    } else {
      return next.handle(request);
    }
  }

  private getClientToken(): Observable<ClientToken> {
    return this.authService.getClientToken();
  }
}