Skip to content

Instantly share code, notes, and snippets.

@MeerKatDev
Last active November 16, 2019 17:34
Show Gist options
  • Save MeerKatDev/8259f0a284871118d77053a091cbda03 to your computer and use it in GitHub Desktop.
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
#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