· 7 years ago · Oct 21, 2018, 02:08 PM
1require 'base64'
2require 'openssl'
3require 'cgi'
4
5module HmacRequestSigning
6 def inject_signature_header(headers, signature)
7 headers['X-Hmac-Sha256'] = signature
8 headers
9 end
10
11 def request_signature(request)
12 request.headers['X_HMAC_SHA256']
13 end
14
15 def hmac_sha256(key, message)
16 digest = OpenSSL::HMAC.digest('sha256', key, message)
17 # chomp -- the base64 encoded version will have a newline at the end
18 Base64.encode64(digest).chomp
19 end
20
21 def sign_params(verb, host, path, secret_key, params)
22 hmac_sha256(secret_key, serialized_params(verb, host, path, params))
23 end
24
25 def serialized_params(verb, host, path, params)
26 [ verb.to_s.upcase,
27 host,
28 path,
29 canonicalize_params(params) ].join("\n")
30 end
31
32 def canonicalize_params(params)
33 # Make sure we have string keys, otherwise the sort does not work
34 params.keys.sort.map do |key|
35 [CGI.escape(key.to_s), CGI.escape(params[key].to_s)].join('=')
36 end.join('&')
37 end
38end