【问题标题】:Unable to connect to GCP CloudSQL using Private IP address (CORS error preflight missing allow origin header)无法使用私有 IP 地址连接到 GCP CloudSQL(CORS 错误预检缺少允许源标头)
【发布时间】:2021-11-11 09:02:07
【问题描述】:

我正在使用 GCP Cloud SQL 实例来获取数据。当使用其公共 IP 地址访问此 SQL 实例时,连接正在发生并且数据是可见的。但由于安全限制,我只能通过私有 IP 地址访问它。

我按照 Google 文档中的说明对通过私有 IP 地址进行连接的代码进行了更改: (https://cloud.google.com/sql/docs/postgres/connect-app-engine-standard#private-ip_1) (https://cloud.google.com/vpc/docs/configure-serverless-vpc-access#java-8)

  1. ConnectionPoolContextListener.java 文件中:iptypes=Private added

config.addDataSourceProperty("ipTypes", "PRIVATE");

  1. appengine-web.xml 文件中:添加了无服务器 vpc 连接器元素
项目/PROJECTNAME/locations/europe-west1/connectors/CONNECTORNAME 全流量
  1. gitlab-ci.yml 文件中:添加了部署连接器服务的行

deploy_env 名称: 脚本:-gcloud app deploy src/main/webapp/WEB-INF/appengine-web.xml

这些更改不起作用并且进行的 API 调用失败并给出 CORS 错误(跨源资源共享错误预检缺少允许源头)(请参阅屏幕截图) UI CORS Error

应用引擎日志如下: com.zaxxer.hikari.pool.HikariPool throwPoolInitializationException: HikariPool-1 - 池初始化期间出现异常。 (HikariPool.java:587) org.postgresql.util.PSQLException:连接尝试失败。 ... 原因:java.io.IOException:连接被拒绝

使用公共 IP 地址时一切正常,也没有 CORS 错误。但是私有 IP 地址连接失败,不知道这里出了什么问题。

数据库连接代码:

private DataSource createConnectionPool() {
HikariConfig config = new HikariConfig();
config.setJdbcUrl(String.format("jdbc:postgresql://google/%s", 
DB_NAME));
config.setUsername(DB_USER);
config.setPassword(DB_PASS); 
config.addDataSourceProperty("socketFactory", 
"com.google.cloud.sql.postgres.SocketFactory");
config.addDataSourceProperty("cloudSqlInstance", 
CLOUD_SQL_CONNECTION_NAME);
config.addDataSourceProperty("ipTypes", "PRIVATE");
config.setMaximumPoolSize(10);
config.setMinimumIdle(5);
config.setConnectionTimeout(10000); // 10 seconds
config.setIdleTimeout(600000); // 10 minutes
config.setMaxLifetime(1800000); // 30 minutes
DataSource pool = new HikariDataSource(config);
return pool;
}

【问题讨论】:

  • 只需勾选方框... VPC Access 连接器是在与 App Engine 实例相同的项目和相同区域中创建的,对吗? AppEngine 存在多久了?真的老了吗?检查网络页面,您没有看到“旧版”标记您的 App Engine 所在的网络。除非这些,包括一些连接代码会有所帮助(显然删除密码/用户信息,但连接字符串会很好,只是为了确保它的格式正确)。
  • 哦,你的应用现在有 CORS 标头吗?还是它以前只是神奇地工作而现在却不是?
  • VPC连接器与App引擎实例在同一区域。应用引擎网络未标记为旧版。尚未添加 CORS 标头。但是只有当我禁用公共 IP 地址访问并且在我启用公共 IP 后应用程序工作正常时,我才会收到 CORS 错误。我曾经尝试添加 CORS 标头,当时我遇到了 App 引擎版本流量迁移的问题,流量迁移失败。
  • CORS 错误是无关的,可能是由失败的 HTTP 请求引发的。真正的问题是,为什么您的连接被拒绝?
  • 因此查看连接字符串(没有凭据)并了解您要连接的数据库类型会有所帮助(mysql、postgres 等)。

标签: google-app-engine google-cloud-sql ioexception hikaricp


【解决方案1】:

我之前创建的 VPC 连接器有问题。我创建了一个新的 VPC 连接器,其网络和区域与 cloudsql 实例的网络和区域相同,并分配了一个 IP 地址范围,现在这个数据库连接正在发生,数据正在加载,CORS 错误已经消失。

因此,要通过 App 引擎的私有 IP 地址连接到 SQL 实例,我只需进行以下更改:

  1. 创建无服务器 VPC 连接器。
  2. 在 appengine.yml 文件中添加 vpc-connector 元素
  3. 在 ConnectionPoolContextListener.java 文件中包含属性“iptypes”

【讨论】:

    【解决方案2】:

    这就是问题所在。连接字符串中有错误:

    // Not correct
    config.setJdbcUrl(String.format("jdbc:postgresql://google/%s", DB_NAME));
    
    // Should be
    config.setJdbcUrl(String.format("jdbc:postgresql:///%s", DB_NAME));
    

    详情请参阅文档:https://github.com/GoogleCloudPlatform/cloud-sql-jdbc-socket-factory/blob/main/docs/jdbc-postgres.md#creating-the-jdbc-url

    【讨论】:

    • 嗨@enocom,我在 JDBC URL 中进行了此更改,并根据此文档检查了其他属性,仍然是同样的错误。
    • 我验证了这个作品。这就是我所做的:我从github.com/GoogleCloudPlatform/java-docs-samples/tree/master/… 开始。我在指向我的访问连接器的 appengine-web.xml 中添加了一个 vpc 访问连接器设置。然后我部署并看到一切正常。我建议通过相同的练习来找出可能缺少哪些细节。
    猜你喜欢
    • 2021-11-10
    • 2021-06-02
    • 1970-01-01
    • 2021-04-28
    • 2022-09-29
    • 2020-04-25
    • 2015-12-28
    • 2022-07-26
    • 2021-11-27
    相关资源
    最近更新 更多