我目前正試圖讓我的elixir網絡服務器爲Google雲端存儲生成已簽名的網址,以便我可以生成過期的文件網址。 不幸的是,當我嘗試使用生成的URL我收到以下錯誤:如何使用Elixir或Erlang創建Google Cloud Storage簽名的URL?
<Code>SignatureDoesNotMatch</Code>
<Message>
The request signature we calculated does not match the signature you provided. Check your Google secret key and signing method.
</Message>
我能夠生成簽署的網址是通過gsutil工具工作,儘管它是相當緩慢的,並且還可以通過給出的Python的例子在這裏:
Google Cloud Storage Signed URLs Example
我的靈藥當前實現基於上述Python的例子,看起來像這樣:
@default_expiration 1000
def construct_string(http_verb, content_md5, content_type, expiration_timestamp, canonicalized_extension_headers, canonicalized_resource) do
"#{http_verb}\n
#{content_md5}\n
#{content_type}\n
#{expiration_timestamp}\n
#{canonicalized_extension_headers}
#{canonicalized_resource}"
end
def load_secret_pem do
load_local_key_file("/path/to/key")
end
def load_local_key_file(path) do
{ok, pem_bin} = File.read(path)
[rsa_entry] = :public_key.pem_decode(pem_bin)
key = :public_key.pem_entry_decode(rsa_entry)
end
def base64Sign(plaintext) do
key = load_secret_pem()
signature_bytes = :public_key.sign(plaintext, :sha256, key)
Base.url_encode64(signature_bytes)
|> String.replace("-", "%2B")
|> String.replace("_", "%2F")
|> URI.encode_www_form
end
def make_url(verb, path, content_md5 \\ "", content_type \\ "") do
client_id = GCloud.Credentials.client_email() |> URI.encode_www_form
expiration = :os.system_time(:seconds) + @default_expiration
base_url = GCloud.Storage.base_uri() <> path
signature_string = construct_string(verb, content_md5, content_type, expiration, "", path)
url_encoded_signature = base64Sign(signature_string)
IO.puts "#{base_url}?GoogleAccessId=#{client_id}&Expires=#{expiration}&Signature=#{url_encoded_signature}"
end
簽名URL如何使用Elixir或Erlang正確簽名?
我已添加您的建議,現在我的請求已正確格式化,謝謝您的確認。可悲的是,我仍然從Google雲存儲獲得相同的「簽名不匹配」錯誤,我想知道erlang public_key:sign函數是否支持我正在嘗試執行的操作,或者我錯誤地使用了它。 –