Skip to content

Instantly share code, notes, and snippets.

@Gurpartap
Last active December 2, 2016 12:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Gurpartap/6741116c76970042d22febf473be340f to your computer and use it in GitHub Desktop.
Save Gurpartap/6741116c76970042d22febf473be340f to your computer and use it in GitHub Desktop.
Authorize api request with api key and secret
package main
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"net/http"
"time"
)
const (
kAPIKey = "kPz9WCvH4Z" // Not the actual key and secret.
kAPISecret = "f8v4Sq1929Oci6Qr1Y3h40P58emj03G5"
kTimeThreshold = 120 // Seconds
)
func authorize(req *http.Request) int {
// 1. -----
// Collect what we know from the request.
method := req.Method
path := req.URL.Path
dateHeader := req.Header.Get("Date") // e.g. "Tue, 12 Jul 2016 21:21:06 GMT"
authorizationHeader := req.Header.Get("Authorization") // e.g. "hmac kPz9WCvH4Z:(.......hmac hash goes here......)"
// body := req.Body ...
// 2. -----
// Create a date object from date header string.
date, err := time.Parse(time.RFC1123, dateHeader)
// If there's an error parsing the date.
if err != nil {
return 403 // 403 Forbidden
}
// If the date is more than TimeThreshold old.
duration := date.Sub(time.Now())
if duration.Seconds() < -(kTimeThreshold) {
return 403 // 403 Forbidden
}
// 3. -----
// Initiate creating HMAC hash into mac variable (with API Secret – like a password to the hash).
mac := hmac.New(sha256.New, []byte(kAPISecret))
// Specify what we're hashing (as the client side is expected to have also).
// e.g. "GET+/api/v1/ping+Tue, 12 Jul 2016 21:21:06 GMT"
mac.Write([]byte(method + "+" + path + "+" + dateHeader)) // + body
// Create the hmac hash using info provided above.
signature := mac.Sum(nil) // in bytes (binary)
// Create a string representation of bytes.
signatureString := hex.EncodeToString(signature)
// 4. -----
// e.g. "hmac kPz9WCvH4Z:(.......hmac hash goes here......)"
expectedAuthorizationHeader := "hmac " + kAPIKey + ":" + signatureString
if authorizationHeader != expectedAuthorizationHeader {
// Invalid authorization claim.
return 401 // 401 Unauthorized
}
return 200 // 200 OK
}
// Don't store keys in code. Also these aren't the ones to use.
let apiKey = "kPz9WCvH4Z"
let apiSecret = "f8v4Sq1929Oci6Qr1Y3h40P58emj03G5"
let url = NSURL(string: "https://backend.marshmallows.com/api/v1/ping")!
let uri = url.path!
let dateString = NSDate.RFC1123DateFormatter().stringFromDate(NSDate()) // Current date time.
let signature = "\(method.rawValue)+\(uri)+\(dateString)".hmac(.SHA256, key: apiSecret)
let authorizationHeader = "hmac \(apiKey):\(signature)"
Alamofire
.request(method, url.absoluteString, parameters: params, encoding: .JSON, headers: [
"Authorization": authorizationHeader,
"Date": dateString
])
.responseData() { response in
if let error = response.result.error {
print("Error: \(error)")
} else if response.response?.statusCode == 401 {
print(String(data: (response.request?.HTTPBody)!, encoding: NSUTF8StringEncoding))
print("Access forbidden")
} else if let data = response.result.value {
// it works...
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment