首页 > 解决方案 > 使用 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。当我尝试GET从我的 NextJS 服务向我的 API(服务器端,通过getServerSideProps)发出请求时,它会再次触发 IAP 登录页面,而不是点击我的 API。我尝试了一些想法来解决这个问题:

  1. 转发 API 请求中的所有 cookie
  2. 如此处所述设置X-Requested-With标题
  3. 向我的 App Engine 默认服务帐户授予受 IAP 保护的 Web 应用用户权限

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

标签: google-app-enginegoogle-cloud-platformnext.jsgoogle-iapidentity-aware-proxy

解决方案


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

首先,基于您在Cloud Run Service to Service文档页面上的开发。

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

// 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 是不正确的。您需要使用名为的 OAuth2 凭据的客户端 IDIAP-App-Engine-app

好吧,很难理解我在说什么。所以,去控制台,API & Services -> Creentials。从那里,您有一个 OAuth2 客户端 ID 部分。复制该行的客户端 ID 列IAP-App-Engine-app,就像这样

在此处输入图像描述

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

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

在此处输入图像描述


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

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


推荐阅读