【问题标题】:google app engine (spring boot) local testing with data store gives Unauthenticated error谷歌应用引擎(春季启动)本地测试与数据存储给出未经身份验证的错误
【发布时间】:2025-12-29 09:00:06
【问题描述】:

使用数据存储在本地运行的 Google 灵活应用引擎 Spring Boot 项目在保存实体时出现 com.google.cloud.datastore.DatastoreException Unauthenticated 异常。

{
   "timestamp": 1512077140003,
   "status": 500,
   "error": "Internal Server Error",
   "exception": "com.google.cloud.datastore.DatastoreException",
   "message": "Unauthenticated.",
   "path": "/users"
}

错误描述here说请求头没有有效的认证头,但是没有提到在哪里放置认证头。

有人遇到过同样的情况吗?

【问题讨论】:

    标签: google-app-engine google-cloud-datastore


    【解决方案1】:

    规范错误代码: UNAUTHENTICATED

    说明:com.google.cloud.datastore.DatastoreException 仅表示请求没有有效的身份验证凭据。

    建议的操作:不要在未解决问题的情况下重试。在这种情况下,您需要再次检查登录凭据。

    更多阅读可以在此页面上找到https://cloud.google.com/datastore/docs/concepts/errors#error_codes

    解决方案:

    只需运行gcloud beta auth application-default login。 但是我花了半天时间才找到它there。 我认为gcloud init 应该足够了。作为替代方案,您可以通过 Google OAuth2 使用 google 身份验证,但这是一种艰难的方式。

    【讨论】:

      【解决方案2】:

      我最终走向了另一个方向。

      1. 您可以验证和使用远程数据存储,例如Amar mentioned
      2. 您还可以获取凭据,将其存储在本地,使用spring.cloud.gcp.datastore.credentials.location=file://FULL_PATH_TO_THE_CREDENTIALS_FILE 在您的application.properties 中引用它,并且仍然使用远程数据存储;
      3. 但我最喜欢的选择是使用 Datastore 模拟器在本地完全运行它,因此根本不需要身份验证:

      src/test/resources/application.properties

          # if it exists, comment out or delete the following property:
          # spring.cloud.gcp.datastore.credentials.location
      
          # add the following
          spring.cloud.gcp.emulator-enabled=true
      
          # if you're not using environment variables, make sure the following property exists
          spring.cloud.gcp.project-id=your-project-id
      

      请注意,如果您正在运行集成测试,或者混合远程和本地测试,您可能需要为每个测试使用不同的 .properties 文件。

      你的测试课

          private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
      
          private static LocalDatastoreHelper helper;
      
          @BeforeClass
          public static void setUpClass() throws IOException, InterruptedException {
              logger.info("[Datastore-Emulator] start");
              helper = LocalDatastoreHelper.create();
              helper.start();
              logger.info("[Datastore-Emulator] listening on port {}", helper.getPort());
      
              System.setProperty(DatastoreHelper.LOCAL_HOST_ENV_VAR, "localhost:" + helper.getPort());
          }
      
          @AfterClass
          public static void cleanUpClass() throws InterruptedException, TimeoutException, IOException {
              logger.info("[Datastore-Emulator] stop");
              helper.stop();
          }
      
          @Before
          public void init() throws IOException {
              logger.info("[Datastore-Emulator] cleaning data");
              helper.reset();
          }
      

      这种方法非常适用于存储库 (org.springframework.cloud.gcp.data.datastore.repository.DatastoreRepository),但如果您想直接使用 Datastore,您可以使用 check this

      参考

      【讨论】: