使用 IAP 服务到 App Engine 上的服务请求

问题描述

我使用 Google App Engine 来托管多项服务(NextJS SSR 服务和基于 Express 构建的后端 API)。我已经设置了我的 dispatch.yaml 文件以将 /api/* 请求路由到我的 API 服务,所有其他请求都被路由到 default (NextJS) 服务。

dispatch:
  - url: '*/api/*'
    service: api

问题:我还为 App Engine 启用了 Identity-Aware Proxy。当我尝试从 NextJS 服务向 API(服务器端,通过 GET)发出 getServerSideProps 请求时,它会再次触发 IAP 登录页面,而不是点击我的 API。我已经尝试了一些想法来解决这个问题:

  1. 转发 API 请求中的所有 cookie
  2. X-Requested-With 标头设置为提到的 here
  3. 向受 IAP 保护的 Web 应用用户授予我的 App Engine 认服务帐户的权限

但似乎没有任何效果。我已经确认关闭 App Engine 的 IAP 可以让一切按预期运行。来自前端的任何对 API 的请求也按预期工作。是否有我缺少的解决方案或解决方法

解决方法

您需要执行服务到服务呼叫。这不是那么简单,你没有真正的例子。无论如何,我测试过(在 Go 中)并且有效。

首先,基于 Cloud Run Service to Service 文档页面进行开发。

您将在 NodeJS 中拥有这段代码 抱歉,我不是 NodeJS 开发人员,更不是 NexJS 开发人员,您必须适应

// Make sure to `npm install --save request-promise` or add the dependency to your package.json
const request = require('request-promise');

const receivingServiceURL = ...

// Set up metadata server request
// See https://cloud.google.com/compute/docs/instances/verifying-instance-identity#request_signature
const metadataServerTokenURL = 'http://metadata/computeMetadata/v1/instance/service-accounts/default/identity?audience=';
const tokenRequestOptions = {
    uri: metadataServerTokenURL + receivingServiceURL,headers: {
        'Metadata-Flavor': 'Google'
    }
};

// Fetch the token,then provide the token in the request to the receiving service
request(tokenRequestOptions)
  .then((token) => {
    return request(receivingServiceURL).auth(null,null,true,token)
  })
  .then((response) => {
    res.status(200).send(response);
  })
  .catch((error) => {
    res.status(400).send(error);
  });    

此示例不起作用,因为您需要正确的受众。这里,变量是receivingServiceURL。它适用于 Cloud Run(和 Cloud Functions),但不适用于 IAP 背后的 App Engine。您需要使用名为 IAP-App-Engine-app

的 OAuth2 凭据的客户端 ID

好吧,很难理解我在说什么。因此,转到控制台,API 和服务 -> 凭据。从那里,您有一个 OAuth2 客户端 ID 部分。复制 IAP-App-Engine-app 行的 Client ID 列,就像这样

enter image description here

最后一点,请确保您的 App Engine 默认服务帐户有权访问 IAP。并将其添加为 IAP-secured Web App User。服务帐户的格式为 <PROJECT_ID>@appspot.gserviceaccount.com

也不是很清楚。因此,转到 IAP 页面(Security -> Identity Aware Proxy),单击 App Engine 前面的复选框,然后转到页面右侧的权限面板

enter image description here


同时,我可以解释如何在特定服务上停用 IAP(由 NoCommandLine 提出)。 请注意:在遇到问题时停用安全性绝不是一个好主意!!

从技术上讲,您不能停用服务上的 IAP。但是您可以在特定服务上授予 allUsers 作为 IAP-secured Web App User(而不是点击 App Engine 的复选框,而是点击特定服务的复选框)。就像这样,即使使用 IAP,您也授权所有用户访问您的服务。 实际上是一种没有检查的激活。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...