web-component - Angular Web 组件 http 调用不通过客户端 http 拦截器进行路由

标签 web-component angular-http-interceptors

设置:

我有一个 Web 组件 (Angular 10) 在 Angular 10 应用程序中使用。 Web 组件对 Web API 进行 Httpclient 调用以获取一些数据来填充菜单下拉列表。 Web 组件是使用标准方法制作的,以使用 Angular 10 制作 Web 组件。

Web 组件通过主客户端应用程序中的脚本加载。这是来自父应用程序的 angular.json 文件。

1."scripts":
 [
    "projects/web-component-test/src/assets/plugin.bundle.js"
 ]

一切正常,除了我们收到 401 错误(未经授权),因为端点要求用户登录。通过正常工作,还有其他控件根据需要显示在下拉列表中,它获取数据来自 API 调用的数据不会被填充。

流程:

  1. 用户访问网站,然后系统提示登录(使用 keycloak Auth)。
  2. 应用程序加载正常,但 Web 组件尝试加载菜单项时出现 401 错误。

来自父应用的 Http 调用工作正常; jwt token 被添加到调用 protected API 的 header 中。来自子 Web 组件的调用在 header 中没有 jwt token ,因此失败并显示 401 错误。

httpinterceptor:我们在主客户端 应用程序(Web 控件的父级)上有一个httpinterceptor。从主应用程序发出的 Http 调用通过拦截器路由,如果需要, token 将附加到 header 。

从子 Web 组件发出的调用不要击中父应用程序中的拦截器?

问题: 如何通过父级中的 http 拦截器从子 Web 组件路由进行调用,以便添加 token 。

我尝试过的事情: 如果我这样做,我可以让网络组件正常工作:

  1. 当父级加载时,我将 token 存储在本地存储中
  2. 在 Web 组件上使用 http 拦截器,从本地存储中检索 token 并使用它。

** 有效,但我不想在本地存储中存储安全 token 。

当父组件加载子组件时,在子组件的一个属性中传递token

** 同样,我可以让它工作,但不是很安全。

最佳答案

Web 组件是独立于您的主代码库的一段代码,因此当您从 Web 组件发出请求时,您的主应用程序将无法在拦截器中捕获这些请求。

对我来说,它起作用的一件事是为每个请求创建不同的自定义事件:

  • doGetRequest
  • 做PostRequest
  • doPutRequest
  • 执行删除请求

让我快速引导您完成这些事件的一个示例。

在主应用程序中,我正在监听是否触发了这些事件:

this.popupEl.addEventListener('doPostRequest', (info: HTMLElementEventMap | any) => {
            this.performHttpRequest(info.detail);
        });

请注意,从您的网络组件发送的所有信息都可以在您的主应用收到的属性“详细信息”中找到。

在网络组件中,我执行以下操作:

this.doPostRequest.emit({
            url: 'the URL to hit',
            endpointParams: {
                user: 'my user',
                password: '******',
            }
        });

注意:您可以更改要发送的参数的结构。这完全取决于您。

这将触发 API 在主应用程序中的执行,并且当请求从主应用程序执行时,您的拦截器将完成其工作并添加您在那里拥有的任何 JWT。一旦主应用程序收到响应,您将需要在 Web 组件中设置一个新属性以将响应传递给它。像这样:

this.popupEl.apiResponse = {
                webComponentInfo: { ...infoReceivedFromYourWebComponent },
                apiDetails: { ...ResponseFromYourBackend}
            };

最后,在您的 Web 组件中,添加一个监听 apiResponse 属性的新输入:

@Input()
    set apiResponse(apiResponse: RequestParams) {
        if (apiResponse.webComponentInfo.url === 'the URL to hit') {
            // Do what you want in your web component, as you know exactly which URL just got executed.
        }
    }

这样,您就可以让您的主应用继续使用您的拦截器完成其工作,而 Web 组件将不需要处理 JWT 或实际执行请求。 您可能需要考虑的一件事是不允许来自 Web 组件的 Delete 请求,除非您且只有您可以完全控制 Web 组件。您不会想要任何可以对非常重要的 API 执行成功的 DELETE 请求的东西。

希望这对您有所帮助。

关于web-component - Angular Web 组件 http 调用不通过客户端 http 拦截器进行路由,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65468104/

相关文章:

javascript - 检查 Dom 元素是否为原生/无自定义元素

javascript - HTML导入angular2应用程序并传递参数

javascript - `HTMLImports.whenReady` 和 `window.addEventListener(' WebComponentsReady 有什么区别', function(e) {`

javascript - 如何在 shadow dom 中使用全局 css 样式

Angular : How to intercept Server-Sent Event request?

javascript - 我可以将函数作为属性传递给 Web 组件吗?

javascript - Angular 1.3.0 支持 JSON 响应,如何在 Angular 之前覆盖此响应或预解析响应?

Angular 6 使用新的 RxJS 处理 403 响应

angular - HTTP 拦截器使用 Angular 2、4、6、7、8、9 TypeScript 在请求失败时获取状态 0

angular - 请求 header 未从拦截器 Angular 2/4(401 处理)成功更新