当前位置: 首页 > 知识库问答 >
问题:

从Android OAuth2访问谷歌云存储

孟绪
2023-03-14

我试图设计一个应用程序,从我的谷歌云存储帐户下载适当的声音文件。该应用程序不访问用户帐户,但我自己的帐户。

我的阅读让我相信,最合适的模式是服务账户https://code.google.com/p/google-api-java-client/wiki/OAuth2#Service_Accounts

不幸的是,开发人员决定不提供Android的例子。他们确实提供了一个很好的例子,只是简单的Java,这http://samples.google-api-java-client.googlecode.com/hg/storage-serviceaccount-cmdline-sample/instructions.html?r=default

我试图将其应用于Android,但遇到了一些问题。

GoogleCredential credential =
        new GoogleCredential.Builder().setTransport(HTTP_TRANSPORT)
            .setJsonFactory(JSON_FACTORY).setServiceAccountId(SERVICE_ACCOUNT_EMAIL)
            .setServiceAccountScopes(STORAGE_SCOPE)
            .setServiceAccountPrivateKeyFromP12File(new File("key.p12")).build();

在谷歌的例子中,他们传递key. p12文件,然而在Android系统上,当我把文件放在res/row文件夹中时,我访问它的唯一方法似乎是作为输入流。我找不到一种优雅的方法来将文件传递给JSON。

这一切让我相信我一定做错了什么。我应该用钥匙吗。p12我应该使用“服务账户模式”吗。有什么例子吗/

谢谢瑞安

更新我成功地实现了让它工作的目标,但我的解决方案对我来说很笨拙,我确信这不是我想要的方式

我所做的就是加上钥匙。p12作为原始/资源,我将其作为输入流打开。然后我使用示例中所示的库将其转换为私钥。

http://www.flexiprovider.de/examples/ExampleSMIMEsign.html

我的代码是这样的

Security.addProvider(new de.flexiprovider.core.FlexiCoreProvider());
    // Next, we have to read the private PKCS #12 file, since the the
    // private key used for signing is contained in this file:
    DERDecoder dec = new DERDecoder(getResources().openRawResource(
            R.raw.key));
    PFX pfx = new PFX();
    try {
        pfx.decode(dec);
        SafeBag safeBag = pfx.getAuthSafe().getSafeContents(0)
                .getSafeBag(0);
        PKCS8ShroudedKeyBag kBag = (PKCS8ShroudedKeyBag) safeBag
                .getBagValue();
        char[] password = "my password from google api".toCharArray();
        privKey = kBag.getPrivateKey(password);
        new AsyncLoadStorage(this).execute();
    } catch (ASN1Exception e) {

但整个事情很难看,我想要一个更干净的解决方案

共有3个答案

莫泓
2023-03-14

我不知道你的具体情况,但你能把这些文件完全公开,这样下载它们就不需要授权吗?

罗烨霖
2023-03-14

下面是我所做的将inputStream键转换为Private ateKey对象:

PrivateKey serviceAccountPrivateKey = SecurityUtils.loadPrivateKeyFromKeyStore(SecurityUtils.getPkcs12KeyStore(), MyClass.class.getResourceAsStream("/privatekey.p12"), "notasecret", "privatekey", "notasecret");

    // Build service account credential.
    GoogleCredential credential = new GoogleCredential.Builder().setTransport(httpTransport)
        .setJsonFactory(jsonFactory)
        .setServiceAccountId(ACCOUNT_ID)
        .setServiceAccountScopes(Collections.singleton(StorageScopes.DEVSTORAGE_FULL_CONTROL))
        //.setServiceAccountPrivateKeyFromP12File(f)
        .setServiceAccountPrivateKey(serviceAccountPrivateKey)
        .build();
夏侯华彩
2023-03-14

谷歌文档实际上是相当误导的。他们还没有更新他们的控制台链接(继续要求你查找“注册应用”链接,该链接不存在),而且他们针对GCS的JAVA api在Android中不起作用(GcsService service=GcsServiceFactory.createGcsService();)。似乎他们希望你只能通过应用引擎访问地面军事系统。

所以,这是一个人需要做的:

  • 你可能不希望用户必须登录GCS或谷歌(想想Snapchat应用)

这对我来说没有任何问题:

        String STORAGE_SCOPE = "https://www.googleapis.com/auth/devstorage.read_write";
        JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();

        Log.d("testing", "checking if I can create a credential");
        httpTransport = AndroidHttp.newCompatibleTransport();
        KeyStore keystore = KeyStore.getInstance("PKCS12");
        keystore.load(resources_.openRawResource(R.raw.gcs_privatekey),
                "password".toCharArray());

        PrivateKey key = (PrivateKey) keystore.getKey("privatekey", "password".toCharArray());

        GoogleCredential credential = new GoogleCredential.Builder()
                .setTransport(httpTransport)
                .setJsonFactory(JSON_FACTORY)
                .setServiceAccountPrivateKey(key)
                .setServiceAccountId(SERVICE_ACCOUNT_EMAIL)
                .setServiceAccountScopes(Collections.singleton(STORAGE_SCOPE))
                // .setServiceAccountUser(SERVICE_ACCOUNT_EMAIL)
                // .setClientSecrets(CLIENT_ID, CLIENT_SECRET)
                .build();
        credential.refreshToken();

        String URI = "https://storage.googleapis.com/" + BUCKET_NAME;
        HttpRequestFactory requestFactory = httpTransport.createRequestFactory(credential);
        GenericUrl url = new GenericUrl(URI);
        HttpRequest request = requestFactory.buildGetRequest(url);
        HttpResponse response = request.execute();
        String content = response.parseAsString();
        Log.d("testing", "response content is: " + content);
        new Storage.Builder(httpTransport, JSON_FACTORY, credential)
                .setApplicationName("appname").build();
 类似资料:
  • 我正试图通过谷歌云功能访问和更新我的firebase数据库,但它不起作用。 我已经编写了一个云函数,其中我已经初始化了Firebase-admin。 我必须提供service_account初始化管理。 我正在将我的firebase应用程序初始化为 我在谷歌云功能中没有我的服务帐户路径。 是否有任何方法从GOOGLE云函数访问Firebase? 谢谢

  • 我正在使用请求将文件上传到谷歌云存储。 请求是: 我得到以下错误作为响应: 我在某处读到,我需要打开谷歌云存储JSON API。是否必须打开谷歌云存储JSON API,或者是否有其他解决方案来修复此错误?

  • 我使用Reactjs创建一个网站并将其托管在Firebase上,并使用google cloud函数上的和设置,以处理函数。网站有一个

  • 我正在开发一个web应用程序,作为与Google云存储(GCS)的接口。 我正在使用后端服务来检索我存储在GCS上的文件列表及其使用JSON API的URL,并将其返回到我的Web应用程序。然而,我真的无法通过这些URL加载文件,总是返回403禁止。 我不确定GCS身份验证在幕后是如何工作的,也不确定是否可以直接授予对网络应用程序的访问权限。我不确定如何通过超文本传输协议请求附加应用程序鉴别信息。