【问题标题】:Google Bigquery 401 unauthorized error using Service Account使用服务帐户的 Google Bigquery 401 未经授权的错误
【发布时间】:2012-05-20 14:32:05
【问题描述】:

当我在我的计算机上尝试来自this post 的 Michael 的 bigquery sn-p 时遇到了“401 Unauthorized”问题。根据 ryguyrg 的建议,我同步了我的计算机时间(通过单击“立即更新”)并且代码有效。但问题是,过了一段时间,也许几分钟,当我重新运行代码时,它再次失败并出现 401 错误。所以几乎每次我想运行一个大查询请求时,我都必须手动同步我的计算机时间。

我很确定我的计算机运行良好,并且时间与服务器的差异不应超过几毫秒。那么究竟是什么导致了这个问题呢?我应该尝试在请求之前从代码中同步时间还是有更好的方法?

下面是401错误信息供参考:

Exception in thread "main" com.google.api.client.googleapis.json.GoogleJsonResponseException: 401 Unauthorized
    at com.google.api.client.googleapis.json.GoogleJsonResponseException.from(GoogleJsonResponseException.java:159)
    at com.google.api.client.googleapis.json.GoogleJsonResponseException.execute(GoogleJsonResponseException.java:187)
    at com.google.api.client.googleapis.services.GoogleClient.executeUnparsed(GoogleClient.java:115)
    at com.google.api.client.http.json.JsonHttpRequest.executeUnparsed(JsonHttpRequest.java:112)
    at com.google.api.services.bigquery.Bigquery$Jobs$Insert.executeUnparsed(Bigquery.java:1418)
    at com.google.api.services.bigquery.Bigquery$Jobs$Insert.execute(Bigquery.java:1442)
    at BigQueryJavaServiceAccount.main(BigQueryJavaServiceAccount.java:83)

【问题讨论】:

    标签: google-bigquery


    【解决方案1】:

    在这个例子中我遇到了同样的问题。 https://cloud.google.com/bigquery/docs/quickstarts/quickstart-client-libraries

    我试图执行以下命令,但发生 401 错误

    export GOOGLE_APPLICATION_CREDENTIALS=/Users/mattheu/credentialFileName.json

    我使用下面解决了凭据问题

    String jsonPath = "/Users/mattheu/credentialFileName.json";
            GoogleCredentials credentials = GoogleCredentials.fromStream(new FileInputStream(jsonPath));
    
    package com;
    
    import com.google.auth.oauth2.GoogleCredentials;
    import com.google.cloud.bigquery.*;
    
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.util.UUID;
    
    public class App {
        public static void main(String[] args) throws InterruptedException, IOException {
            String jsonPath = "/Users/mattheu/credentialFileName.json";
            GoogleCredentials credentials = GoogleCredentials.fromStream(new FileInputStream(jsonPath));
    
            BigQuery bigquery = BigQueryOptions.newBuilder()
                    .setCredentials(credentials)
                    .build().getService();
    
            QueryJobConfiguration queryConfig =
                    QueryJobConfiguration.newBuilder(
                            "SELECT "
                                    + "CONCAT('https://stackoverflow.com/questions/', CAST(id as STRING)) as url, "
                                    + "view_count "
                                    + "FROM `bigquery-public-data.stackoverflow.posts_questions` "
                                    + "WHERE tags like '%google-bigquery%' "
                                    + "ORDER BY favorite_count DESC LIMIT 10")
                            // Use standard SQL syntax for queries.
                            // See: https://cloud.google.com/bigquery/sql-reference/
                            .setUseLegacySql(false)
                            .build();
    
            // Create a job ID so that we can safely retry.
            JobId jobId = JobId.of(UUID.randomUUID().toString());
            Job queryJob = bigquery.create(JobInfo.newBuilder(queryConfig).setJobId(jobId).build());
    
            // Wait for the query to complete.
            queryJob = queryJob.waitFor();
    
            // Check for errors
            if (queryJob == null) {
                throw new RuntimeException("Job no longer exists");
            } else if (queryJob.getStatus().getError() != null) {
                // You can also look at queryJob.getStatus().getExecutionErrors() for all
                // errors, not just the latest one.
                throw new RuntimeException(queryJob.getStatus().getError().toString());
            }
    
            QueryResponse response = bigquery.getQueryResults(jobId);
    
            TableResult result = queryJob.getQueryResults();
    
            // Print all pages of the results.
            for (FieldValueList row : result.iterateAll()) {
                String url = row.get("url").getStringValue();
                long viewCount = row.get("view_count").getLongValue();
                System.out.printf("url: %s views: %d%n", url, viewCount);
            }
        }
    }
    

    结果:
    网址:What is Google's Dremel? How is it different from Mapreduce? 浏览次数:27736
    网址:Unable to access BigQuery from local App Engine development server 浏览量:4732
    网址:How do I use the TABLE_QUERY() function in BigQuery? 浏览量:9674
    网址:Migrating from non-partitioned to Partitioned tables 浏览量:3549
    网址:How can I undelete a BigQuery table? 浏览量:3332
    网址:Google App Engine: Using Big Query on datastore? 浏览量:6928
    网址:Random Sampling in Google BigQuery 浏览量:11635
    网址:How to use Bigquery streaming insertall on app engine & python 浏览量:4279
    网址:Delete duplicate rows from a BigQuery table 浏览量:8552
    网址:How to improve performance of GeoIP query in BigQuery? 浏览量:3213

    【讨论】:

      【解决方案2】:

      我会首先确保您的时间是使用 ntpd 同步的,并且它设置为您的正确时区:http://www.ntp.org/

      【讨论】:

        【解决方案3】:

        几毫秒不应该影响它。

        最大的失败可能性是,如果您的请求是在未来发生的 - Google 的服务器肯定会拒绝这些请求。

        我同意 Michael 关于通过 NTP 同步的建议。

        我们也可以考虑让我们的 OAuth 服务稍微更宽松一些 - 但平衡安全性和可用性总是很困难

        【讨论】:

          猜你喜欢
          • 2018-10-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-09-19
          • 2017-02-23
          • 1970-01-01
          相关资源
          最近更新 更多