使用JSON API将文件上传到Google云端存储,错误401未经授权

时间:2016-02-23 03:32:53

标签: android google-cloud-storage google-cloud-platform

我正在尝试弄清楚如何使用Android中的JSON API将图片上传到Google Cloud Storage,但这样做的文档似乎非常有限。

我相信我遇到的问题是获得正确的API密钥身份验证。上传的图片是公开但仅向我的应用用户公开的图片,因此阅读Authorize Requests文档说明我不需要为公共数据提供OAuth密钥,我只需发送一个API密钥即可

  

公共API访问:不提供OAuth 2.0令牌的请求   必须发送API密钥。密钥标识您的项目并提供API   访问,配额和报告。

所以我去了我的控制台,从我的调试和生产密钥库的(API Manager/Credentials/Create Credentials/API Key)创建了一个密钥SHA1

这些API密钥是正确的,因为它们与google sign-in等其他Google服务一起使用,并且运行正常。

当我尝试发出可恢复上传的请求时,这就是我的工作

String sUrl = "https://www.googleapis.com/upload/storage/v1/b/myBucket/o?uploadType=resumable&name="+mImgName;
URL url = new URL(sUrl);
HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
urlConnection.setRequestProperty("Authorization","AIzaSyDT....");
urlConnection.setRequestProperty("X-Upload-Content-Type","image/png");
urlConnection.setRequestProperty("X-Upload-Content-Length",String.valueOf(fileSize));
urlConnection.setRequestMethod("POST");

然而我回来Error 401 Unauthorized所以我认为这是我发送的密钥的问题。

我还在Authorize Requests文档末尾看到它声明我可以将我的密钥作为请求网址的参数

  

拥有API密钥后,您的应用程序可以附加查询   参数key =所有请求URL的yourAPIKey。

所以我不知道我是否想要这样做或者在请求中设置Authorization属性或两者都有?

关键是我创建了错误类型的密钥,或者我在这里缺少什么?

2 个答案:

答案 0 :(得分:1)

您可以使用API​​密钥下载公共对象。

但是,除非您的存储桶启用了公共写入(通常您不想这样做),否则您仍需要使用身份验证来上传到存储桶。

在您的情况下,我认为您可能想要使用Signed URLs

答案 1 :(得分:0)

在查看@jterrace建议的签名URL时,我发现由于我需要一个可恢复的URL,我可以在没有客户端身份验证的情况下使用它

  

如果您的用户仅将资源(写入)上传到   访问控制桶,您可以使用可恢复的上传   Google云端存储的功能,并避免签名或   需要Google帐户。在可恢复的上传方案中,您的   (服务器端)代码验证并启动上传到Google   云存储没有实际上传任何数据。启蒙   request返回一个会话URI,然后可以在客户端中使用   请求上传数据。客户端请求不需要   签名是因为会话URI实际上充当了身份验证   令牌。

所以我做的是让我的App Engine后端创建可恢复的网址,然后将其传递给我的客户端,并在后端获取身份验证令牌

List<String> scopes = new ArrayList<>();
scopes.add("https://www.googleapis.com/auth/devstorage.full_control");
AppIdentityService appIdentity = AppIdentityServiceFactory.getAppIdentityService();
AppIdentityService.GetAccessTokenResult accessToken = appIdentity.getAccessToken(scopes); 
urlConnection.setRequestProperty("Authorization","Bearer "+accessToken.getAccessToken());