Last active
November 16, 2019 17:34
-
-
Save MeerKatDev/8259f0a284871118d77053a091cbda03 to your computer and use it in GitHub Desktop.
Sign a request for Aliyun OSS (i.e. how to create the Authorization header) in Elixir
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#first, we need to obtain a converter to GMT, needed for the Date header | |
# GMT format: "Sun, 22 Nov 2015 08:16:38 GMT" | |
defp utc_to_gmt(utc_datetime) do | |
# format = "{WDshort}, {0D} {Mshort} {YYYY} {h24}:{m}:{s} GMT" | |
days = ["Mon","Tue","Wed","Thu","Fri","Sat","Sun"] | |
months = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"] | |
day_of_week = Date.day_of_week(utc_datetime) | |
month = Enum.at(months,utc_datetime.month-1) | |
year = utc_datetime.year | |
time = to_string(Time.truncate(DateTime.to_time(utc_datetime),:second)) | |
day_of_month = String.length(to_string(utc_datetime.day))==1 && "0#{utc_datetime.day}" || to_string(utc_datetime.day) | |
day_of_week = Enum.at(days,day_of_week-1) | |
"#{day_of_week}, #{day_of_month} #{month} #{year} #{time} GMT" | |
end | |
# this is valid for e.g. get requests. | |
# Based on: https://www.alibabacloud.com/help/doc-detail/31951.htm?spm=a2c63.p38356.b99.152.36eb66fc9Iw1Iu#h2-url-5 | |
defp build_auth_signature( | |
method \\ :post, # REST protocol used | |
date \\ get_gmt_date(), # time of the request | |
content_type \\ "application/json", # the format of the request | |
can_headers \\ "/BucketName/Resource", # the absolute url of the resource requested | |
oss_headers \\ ["x-oss-sth": "", ...], # optional, can stay empty for most requests | |
body \\ "" # optional, for simple get requests may stay empty | |
) do | |
verb = Atom.to_string(method) |> String.upcase() | |
md5_header = (body == "") && "" || md5_content(body) | |
oss_string = (Enum.count(oss_headers) == 0) && "" || ( | |
(Enum.map(oss_headers, fn{k,v} -> k <> ":" <> v end) |> Enum.join("\n")) <> "\n") | |
string_to_sign = verb <> "\n" | |
<> md5_header <> "\n" | |
<> content_type <> "\n" | |
<> date <> "\n" | |
<> oss_string | |
<> can_headers | |
signature = :crypto.hmac(:sha, @access_key_secret,string_to_sign) | |
|> Base.encode64() | |
"OSS " <> @access_key_id <> ":" <> signature | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment