首页 文章

授权给Google客户端

提问于
浏览
3

我正在编写一个用于为Bigquery和Google Cloud Storage创建授权的课程 . 在过去,我使用过已弃用的CredentialStore . 我正在尝试使用DataStoreFactory,但我发现它允许我在需要Credential时仅使用StoredCredential . 我知道可以从Credential转换为StoredCredential但我不确定如何将它们转换为相反的方向(StoredCredential to Credential) . 我使用例如Storage.Builder(HttpTransport传输,JsonFactory jsonFactory,HttpRequestInitializer httpRequestInitializer)创建我的连接

有人能指出我如何实现这个目标吗?谢谢!

2 回答

  • 1

    在大多数情况下,无论您使用Credential,都可以使用StoredCredential . 您将使用Credential只有一点,即在OAuth回调期间检索访问令牌 . 从那里,Credential可以转换为StoreCredential并存储到DataStore中 . 在存储和检索之后,所有工作都与StoredCredential一起使用 .

    但有些地方被StoredCredential无法使用 . 我刚遇到一个尝试创建Google Drive API服务包装器的人 .

    有一种方法可以使用GoogleCredential对象来解决这个问题,可以根据此答案从StoredCredential创建它:Stored Credential from google api to be reused java

    import com.google.api.client.auth.oauth2.StoredCredential;
    
    public static GoogleCredential createGoogleCredential(StoredCredential storedCredential)
    {
        HttpTransport httpTransport = new NetHttpTransport();
        JsonFactory jsonFactory = new JacksonFactory();
        GoogleCredential googleCredential = new GoogleCredential.Builder()
            .setTransport(httpTransport)
            .setJsonFactory(jsonFactory)
            .setClientSecrets("client_id", "client_secret").build();
        googleCredential.setAccessToken(storedCredential.getAccessToken());
        return googleCredential;
    }
    
  • 0

    我正在使用google-oauth-client-1.22.0.jar .

    我有一个带有静态Service Account凭据的Java服务器,可通过Google Cloud进行身份验证 .

    这是我使用的重要代码 .

    这里的关键是添加 CredentialRefreshListener ,当您成功通过身份验证后,Google OAuth客户端库将调用并为您提供一个可以序列化和存储的 StoredCredential 对象 . 通过编写或实例化 DataStore 接口的实现,将其存储并检索到您选择的位置 . 您的 DataStore 实现是使用 DataStoreFactory 实现构造的 .

    在构建 GoogleCredential 之后,我可以从 DataStore 读取最后一个访问令牌,刷新令牌和到期日期 . 如果访问令牌即将过期,或者这是第一次调用此代码,则Google客户端API将调用刷新侦听器,它将存储第一个访问令牌,刷新令牌和到期日期 .

    import com.google.api.client.auth.oauth2.DataStoreCredentialRefreshListener;
    import com.google.api.client.auth.oauth2.StoredCredential;
    import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
    import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
    import com.google.api.client.http.HttpTransport;
    import com.google.api.client.json.JsonFactory;
    import com.google.api.client.json.jackson2.JacksonFactory;
    import com.google.api.client.util.IOUtils;
    import com.google.api.client.util.store.AbstractDataStore;
    import com.google.api.client.util.store.AbstractDataStoreFactory;
    import com.google.api.client.util.store.DataStore;
    import com.google.api.client.util.store.DataStoreFactory;
    import com.google.api.services.storage.Storage;
    import com.google.api.services.storage.StorageScopes;
    import com.google.api.services.storage.model.StorageObject;
    
    import java.io.IOException;
    import java.io.Serializable;
    import java.util.Base64;
    
    public class StackOverflow {
    
      public static void main(final String... args) throws Exception {
        final String clientEmail = "todd.snider@aimless.com";
        final HttpTransport transport = GoogleNetHttpTransport.newTrustedTransport();
        final JsonFactory jsonFactory = new JacksonFactory();
        // This implementation generates an that stores and retrieves StoredCredential objects
        final DataStoreFactory dataStoreFactory = new AbstractDataStoreFactory() {
          @Override
          protected <V extends Serializable> DataStore<V> createDataStore(final String id) {
            return new MyDataStore<>(this, id);
          }
        };
        // construct a GoogleCredential object to access Google Cloud
        final GoogleCredential credential = new GoogleCredential.Builder()
            .setTransport(transport)
            .setJsonFactory(jsonFactory)
            .setServiceAccountId(clientEmail)
            .setServiceAccountScopes(StorageScopes.all())
            .setServiceAccountPrivateKey(readEncryptedPemFile())
            .setServiceAccountPrivateKeyId("___static_get_this_from_google_console___")
            .addRefreshListener(new DataStoreCredentialRefreshListener(clientEmail, dataStoreFactory))
            .build();
        // See I have an access token, refresh token and expiration date stored in my DataStore.
        // If so, set them on the GoogleCredential
        final StoredCredential storedCredential = StoredCredential.getDefaultDataStore(dataStoreFactory).get(clientEmail);
        if (storedCredential != null) {
          credential.setAccessToken(storedCredential.getAccessToken());
          credential.setRefreshToken(storedCredential.getRefreshToken());
          credential.setExpirationTimeMilliseconds(storedCredential.getExpirationTimeMilliseconds());
        }
        // Now I can use Google Cloud
        final Storage storage = new Storage.Builder(credential.getTransport(), credential.getJsonFactory(), credential).setApplicationName("Aimless").build();
        storage.objects().insert("soem bucket", new StorageObject());
      }
    
      private static class MyDataStore<V extends Serializable> extends AbstractDataStore<V> {
    
        MyDataStore(DataStoreFactory dataStoreFactory1, String id1) {
          super(dataStoreFactory1, id1);
        }
    
        @Override
        public DataStore<V> set(String key, V value) throws IOException {
          final String encoded = Base64.getEncoder().encodeToString(IOUtils.serialize(value));
          db.save(key, encoded);
          return this;
        }
    
        @Override
        public V get(String key) throws IOException {
          final String encoded = db.get(key);
          if (encoded == null) {
            return null;
          }
          return IOUtils.deserialize(Base64.getDecoder().decode(encoded));
        }
    
        // etc.
      }
    

相关问题