问题简介
我有一个在 GKE 中运行的 gRPC 服务。我正在使用 Cloud Endpoints 并在其前面有一个 ESP(可扩展服务代理),我想用它来处理身份验证(JWT 令牌)。
这听起来像是将所有这些工具集成在一起的一种非常好的方式,但是在过去的两天里,我一直无法让它工作。在本地运行时,我可以完美地连接和拨打电话,但事实证明,通过 ESP 很难设置。
注意:我最终想打开一个 http2 端口,但我现在的重点是获得浏览器支持,所以我只是打开了 http 端口
K8s 部署和服务配置
我的服务正在运行和工作,我正在使用这个清单部署它
apiVersion: v1
kind: Service
metadata:
name: esp-grpc-environment
spec:
ports:
# Port that accepts gRPC and JSON/HTTP2 requests over HTTP.
- port: 80
targetPort: 9090
protocol: TCP
name: http2
selector:
app: esp-grpc-environment
type: LoadBalancer
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: esp-grpc-environment
spec:
replicas: 1
template:
metadata:
labels:
app: esp-grpc-environment
spec:
containers:
- name: esp
image: gcr.io/endpoints-release/endpoints-runtime:1.16.0
args: [
"--http_port=9090",
"--service=environment.endpoints.olamai-d64a7.cloud.goog",
"--rollout_strategy=managed",
"--backend=grpc://127.0.0.1:8000",
"--cors_preset=basic",
"--cors_allow_headers=Keep-Alive,User-Agent,Cache-Control,Content-Type,Content-Transfer-Encoding,X-Accept-Content-Transfer-Encoding,X-Accept-Response-Streaming,X-User-Agent,X-Grpc-Web,Grpc-Timeout,Authorization,authorization",
"--cors_expose_headers=grpc-status,grpc-message,authorization"
]
ports:
- containerPort: 9090
- name: environment
image: terrariumai/environment:0.0.1
imagePullPolicy: Always
ports:
- containerPort: 8000
所以我最初只是使用我自己的 nginx 代理,但我决定想要 Endpoints 的功能。有了这个和很多错误,我得到了 ESP 的所有 Cors 参数。
这是带有身份验证设置的配置
type: google.api.Service
config_version: 3
name: environment.endpoints.<project id>.cloud.goog
title: Environment gRPC API
apis:
- name: endpoints.terrariumai.environment.Environment
authentication:
providers:
- id: firebase
jwks_uri: https://www.googleapis.com/service_accounts/v1/metadata/x509/securetoken@system.gserviceaccount.com
issuer: https://securetoken.google.com/<project-id>
rules:
- selector: "*"
requirements:
- provider_id: firebase
usage:
rules:
- selector: endpoints.terrariumai.environment.Environment.CreateEntity
allow_unregistered_calls: true
使用 Node/React 调用服务
所以一旦它运行和部署,我使用我的 React 应用程序像这样点击服务
import {
CreateEntityRequest
} from "../api/environment_pb";
this.props.firebase
.auth()
.currentUser.getIdToken(/* forceRefresh */ true)
.then(function(idToken) {
var service = new EnvironmentClient(addr, null, null);
var request = new CreateEntityRequest();
var metadata = {
authorization: `Bearer ${idToken}`
};
console.log(idToken);
service.createEntity(request, metadata, (err, resp) => {
if (err) {
console.log("Got error: ", err);
}
console.log("Resp: ", resp);
});
})
从这里,我得到了这个错误
POST http://<external-ip>/endpoints.terrariumai.environment.Environment/CreateEntity 403 (Forbidden)
但在这一点上,我很困惑。这是来自 ESP pod 的日志(我无法阅读)
[09/Jul/2019:20:40:49 +0000] "POST /endpoints.terrariumai.environment.Environment/CreateEntity HTTP/1.1" 403 210 "http://localhost:3000/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36"
对我来说,似乎 ESP 拒绝了这些呼叫并说它们是被禁止的(可能没有经过身份验证??)。但在这一点上,我被难住了。我真的不知道该往哪里看。我会很感激任何帮助,如果有必要可以提供更多信息!