Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 通过签名URL将文件放入谷歌云存储(GCS)_Java_Google Cloud Storage - Fatal编程技术网

Java 通过签名URL将文件放入谷歌云存储(GCS)

Java 通过签名URL将文件放入谷歌云存储(GCS),java,google-cloud-storage,Java,Google Cloud Storage,我正在尝试使用“签名URL”访问/上传文件到谷歌云存储(GCS) 按照 我所做的: 在谷歌云控制台注册了一个“Web应用程序” 使用注册web应用程序屏幕“证书”部分的“生成新密钥”生成新私钥 创建要签名的字符串,并使用页面“如何签名”部分提供的示例代码对其进行签名(只是对Java主程序的硬代码值进行了一些小调整)。更新:创建了一个要点 确保签名字符串是URL编码的 指定的HTTP头:x-goog-api-version、x-goog-project-id、内容类型 指定的URL参数:Goog

我正在尝试使用“签名URL”访问/上传文件到谷歌云存储(GCS)

按照

我所做的:

  • 在谷歌云控制台注册了一个“Web应用程序”
  • 使用注册web应用程序屏幕“证书”部分的“生成新密钥”生成新私钥
  • 创建要签名的字符串,并使用页面“如何签名”部分提供的示例代码对其进行签名(只是对Java主程序的硬代码值进行了一些小调整)。更新:创建了一个要点
  • 确保签名字符串是URL编码的
  • 指定的HTTP头:x-goog-api-version、x-goog-project-id、内容类型
  • 指定的URL参数:GoogleAccessId、签名、过期
  • 使用Postman(Chrome扩展)模拟PUT请求
然而,我仍然得到这个(状态:403禁止):

即使我根据“StringToSign”中的值对字符串进行签名重试,我仍然会收到相同的错误

阅读这里的各种相关帖子,但找不到任何解决方案,其中大部分都是在我使用版本2时引用的
x-goog-api-version:1


我错过了什么?任何帮助都将不胜感激。

在查看您的代码时,是否可以通过省略以下标题尝试创建stringToSign-

"x-goog-api-version:2\n" +
"x-goog-project-id:1234\n" +
如下图所示-

 String stringToSign = "PUT\n" +
                "\n" +
                "text/plain\n" +
                "1384084959392\n" +
                "/test-bucket/bob.txt";
现在尝试生成签名URL


谢谢

终于成功地使用签名URL将文件放入谷歌云存储。通过创建一个简单的Java程序来模拟:

  • Server
    对字符串进行签名并将其编码为签名
  • Uploader
    作为未经身份验证的用户,仅使用
    服务器提供的签名提交PUT请求。使用Apache的HTTP客户端库模拟浏览器
你可以在这里看到


当我通过Chrome的Postman扩展提交时,我真的不明白为什么它不起作用。

要从浏览器运行签名url,必须设置HTTP头。 在

内容类型可选。如果您提供此值,客户端(浏览器)必须将此HTTP头设置为相同的值。有一个词必须


因此,如果您为符号字符串提供内容类型,则必须在浏览器http标头中提供相同的内容类型。在浏览器标头中设置内容类型时,我也遇到了同样的问题,因此我可以下载文档。

尽管文档中说
内容类型是可选的,它实际上意味着您必须将http请求头对应的
内容类型设置为正确的

在这种情况下,您必须在签名字符串中添加
内容类型:text/plain


我一直在努力解决PUT和签名URL(使用GAE云端点)的问题,但以下是我需要做的两件事:

  • 确保您拥有最新的GAE gradle依赖项。自动生成的,但android studio并不总是最新的
  • 对于PUT,您需要让字符串签名如下:

    字符串url\u signature=sign(动词+“\n”+contentMD5+“\n”+contentType+“\n”+expiration+“\n”+“/”+BUCKET\u NAME+“/”+objectName)

  • 如下所述:格式为:

    StringToSign = HTTP_Verb + "\n" +
                   Content_MD5 + "\n" +
                   Content_Type + "\n" +
                   Expiration + "\n" +
                   Canonicalized_Extension_Headers +
                   Canonicalized_Resource
    

    返回“\n”的内容很重要。如果你有太多或不够,你会得到这个错误。例如,如果您没有传递contentMD5,只需传入一个空字符串,即可获得正确的返回数“\n”

    你能发布你用来执行签名的代码吗?@jterrace我已经为修改后的GcsSigner.java-@kctang创建了一个要点。你能发布一个用给定代码构建的完整签名URL示例吗?嗨,kctang。我刚刚看过你的演示应用程序。在该文件中,我无法找出什么是公共静态最终字符串键\u FILENAME=“my privatekey.p12”;公共静态最终字符串密钥\u PASSWORD=“notacret”;。你能告诉我文件里的那些字段是什么吗。就连我也在使用谷歌云存储来上传文件。@Santosh你可以从谷歌的开发控制台创建这些类型的客户端ID。太好了。我也在寻找解决办法。你救了我的命。你能告诉我如何用表格上传文件吗。比如在表单中提供所有参数。我想从表单上传一个文件到谷歌云存储。我无法准备签名和保单。你能告诉我程序吗。等待您的响应。过期时间必须以秒为单位,而不是像您的程序那样以毫秒为单位。@kctang,我认为这在Chrome的Postman中不起作用,因为您可能忘记在标题中发送相同的内容类型。我使用Postman,但需要发送与签名URL中使用的内容类型相同的内容类型。根据我的经验,在大多数情况下,它也可以工作,而无需指定它。。。。i、 e.对于简单的文本文件,至少我确信-我在生产中使用它,它可以工作;对于更复杂的格式,它可能并不总是能够推断它。。。因此,明确设置它仍然是一种良好的做法;-)
    StringToSign = HTTP_Verb + "\n" +
                   Content_MD5 + "\n" +
                   Content_Type + "\n" +
                   Expiration + "\n" +
                   Canonicalized_Extension_Headers +
                   Canonicalized_Resource