【问题标题】:Getting CORS error in GCP while IAP is enabled on App engine在 App 引擎上启用 IAP 时在 GCP 中出现 CORS 错误
【发布时间】:2022-09-27 16:53:21
【问题描述】:

我们将 App Engine 中的前端(angular 14)和后端(python flask)部署为两个不同的服务并启用了 IAP。 IAP 只允许授权用户访问网页。

当我们点击前端端点时,会出现一个 google SSO 页面来进行身份验证。允许授权用户访问网页。

从角度来看,我们使用库进行 SSO 登录https://www.npmjs.com/package/angular-oauth2-oidc获取授权用户详细信息和 BEARER 令牌。

我们将 BEARER 令牌存储在本地存储下。

localStorage.setItem(\"token\",this.oAuthService.getIdToken());

当我们与后端端点交互以授权用户并获取数据时,将 BEARER 令牌添加到请求 HEADER 中。

token= localStorage.getItem(\'token\')
  
  headers = new HttpHeaders({
  \'Content-Type\': \'application/json\',
  \'Cache-Control\': \'no-cache\',
      \"Access-Control-Allow-Origin\": \"*\",
      \"Access-Control-Allow-Methods\": \"GET, POST, PUT, DELETE, PATCH, OPTIONS\",
      \"Access-Control-Allow-Headers\": \"X-Requested-With, Content-Type, Authorization\",
      \"Access-Control-Allow-Credentials\": \"true\",
      \"Authorization\":\"Bearer \"+this.token,
      //\'Authorization\': `Bearer ${this.token}`

    })
postMonitoringDataById(monitoring: Monitoring){
   return this.http.post(environment.baseUrl+environment.MONITORING_SCREEN_DATA,monitoring,{ 
     headers: this.headers});


应用上述功能后,当我们从前端向后端发送请求时出现 CORS 错误(错误如下所示)

从源 \'http://angular-end-point\' 访问位于 \'https://python-end-point/getData\' 的 XMLHttpRequest 已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:它没有 HTTP ok 状态。

Browser Error

在后端,我们处理 CORS 策略

app = Flask(__name__)
#CORS(app)
cors = CORS(app, resources={r\"/*\": {\"origins\": \"*\"}}, supports_credentials=True)

app.config[\'CORS_HEADERS\'] = \'Content-Type\'

@app.before_request
def basic_authentication():
    logger.info(\"preflight before request\")
    if request.method.lower() == \'options\':
        # return \"OK\",200
        return Response(status=200)
@app.after_request
def after_request(response):
    logger.info(\"set headers\")
    # response.headers.add(\'Access-Control-Allow-Origin\', \'*\')
    origin = request.headers.get(\'Origin\')
    if origin:
        response.headers.set(\'Access-Control-Allow-Origin\', origin)
    else:
        response.headers.add(\'Access-Control-Allow-Origin\', \'*\')
    response.headers.add(\'Access-Control-Allow-Headers\', \'Content-Type,Authorization\')
    response.headers.add(\'Access-Control-Allow-Methods\', \'GET,PUT,POST,DELETE,OPTIONS\')
    response.headers.add(\'Access-Control-Allow-Credentials\', \'true\')
    return response

@app.route(\'/getData\', methods=[\"GET\", \"POST\", \"OPTIONS\"])
def get_monitoring_screen_data():

同样对于 CORS 错误,我们在 app.yaml 文件中添加了 http 标头

handlers:
- url: /favicon.ico
  static_files: static/images/favicon.ico
  upload: static/images/favicon.ico
  http_headers:
    Access-Control-Allow-Origin: \"*\"
    Access-Control-Allow-Headers: \"*\"

当我们检查 GCP 日志时,前端请求未与后端服务通信。 Flask 应用程序未运行。

GCP log

GCP logs extended

当我们尝试使用 BEARER 令牌从邮递员发送后端请求时,我们得到了预期的结果。

Postman Log

GCP Postman Log

在进一步的研究中,我们找到了解决预检选项请求的文件。

自定义 IAP https://cloud.google.com/iap/docs/customizing

以下是我在 GCP 文档中找到的标题 GCP_IAP_UID GCP_IAAP_AUTH_TOKEN_87657E95ABB28982

我们是否需要在发出后端请求时添加它。

默认情况下,浏览器向后端发送预检请求(OPTION Request)。在烧瓶中,我通过返回响应处理了预检请求调用 状态码为 200,但当我收到来自前端的呼叫时,我的烧瓶服务仍然没有执行。 选项调用没有授权标头,因此我们无法进行身份验证过程。我不确定如何在 OPTIONS 调用期间绕过授权过程。

由于我是 GCP 的新手,请分享您解决此问题的建议

  • 什么是 HTTP 状态码?当发生错误(程序异常)时,通常不会发送 CORS 标头。当实际问题是您的应用程序崩溃时,浏览器会显示 CORS 错误。注意消息它没有 HTTP ok 状态.
  • 嗨@JohnHanley,感谢您的回复。在网络页面下的浏览器中,后端端点的状态显示为 ** CORS: preflightInvalidStatus ** 在 Gcp 日志中它向我们显示 **IAM 权限被拒绝错误 404 ** 我将添加状态图像供您参考研究我们发现,从角度来看,如果我们向任何后端发出任何请求,浏览器都会发送 OPTIONS 请求。此 OPTION 请求未携带 AUTHORAZATION 标头令牌,因为此后端端点未进行身份验证。对于选项请求,我也有一个吸引人的方法(在上面的 stmt 中显示)
  • 我在烧瓶中有一些默认记录器,它们会告诉应用程序已启动,正在记录,但是当前端 api 调用后端 api 时,我无法在 GCP 日志中看到这些记录器。所以 FLASK 服务没有运行,但是当我做邮递员时,我可以看到记录器。请帮助我。 Also can you help me on how to disable authentication in backend when the option request is pass with some code sample .

标签: angular flask google-app-engine google-cloud-platform in-app-purchase


【解决方案1】:

当您与两个不同的服务通信时,您必须在 IAP 中启用 HTTP 选项以避免 preflight CORS 错误。

您已经涵盖了编码逻辑,并且处于最后阶段。 GCP 文档(根据您的研究)https://cloud.google.com/iap/docs/customizing 是正确的。

[HTTP 选项][1]

问题陈述以及解释过程和问题的方式非常好。保持。

快乐编码!

谢谢

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-29
    • 2017-11-21
    • 2017-04-29
    • 1970-01-01
    相关资源
    最近更新 更多