forked from mironal/TwitterAPIKit
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathOAuthHelper.swift
More file actions
74 lines (63 loc) · 2.75 KB
/
OAuthHelper.swift
File metadata and controls
74 lines (63 loc) · 2.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
import CommonCrypto
import Foundation
private let oauthVersion = "1.0"
private let oauthSignatureMethod = "HMAC-SHA1"
func authorizationHeader(
for method: HTTPMethod,
url: URL,
parameters: [String: Any],
consumerKey: String,
consumerSecret: String,
oauthToken: String?,
oauthTokenSecret: String?,
oauthTimestamp: String? = .none,
oauthNonce: String? = .none
) -> String {
var authorizationParameters = [String: Any]()
authorizationParameters["oauth_version"] = oauthVersion
authorizationParameters["oauth_signature_method"] = oauthSignatureMethod
authorizationParameters["oauth_consumer_key"] = consumerKey
authorizationParameters["oauth_timestamp"] = oauthTimestamp ?? String(Int(Date().timeIntervalSince1970))
authorizationParameters["oauth_nonce"] = oauthNonce ?? UUID().uuidString
if let oauthToken = oauthToken {
authorizationParameters["oauth_token"] = oauthToken
}
for (key, value) in parameters where key.hasPrefix("oauth_") {
authorizationParameters.updateValue(value, forKey: key)
}
let combinedParameters = authorizationParameters.merging(parameters) { $1 }
authorizationParameters["oauth_signature"] = oauthSignature(
for: method, url: url, parameters: combinedParameters, consumerSecret: consumerSecret,
oauthTokenSecret: oauthTokenSecret)
let authorizationParameterComponents = authorizationParameters.urlEncodedQueryString.components(
separatedBy: "&"
).sorted()
var headerComponents = [String]()
for component in authorizationParameterComponents {
let subcomponent = component.components(separatedBy: "=")
if subcomponent.count == 2 {
headerComponents.append("\(subcomponent[0])=\"\(subcomponent[1])\"")
}
}
return "OAuth " + headerComponents.joined(separator: ", ")
}
private func oauthSignature(
for method: HTTPMethod,
url: URL,
parameters: [String: Any],
consumerSecret: String,
oauthTokenSecret: String?
) -> String {
let tokenSecret = oauthTokenSecret?.urlEncodedString ?? ""
let encodedConsumerSecret = consumerSecret.urlEncodedString
let signingKey = "\(encodedConsumerSecret)&\(tokenSecret)"
let parameterComponents = parameters.urlEncodedQueryString.components(separatedBy: "&").sorted()
let parameterString = parameterComponents.joined(separator: "&")
let encodedParameterString = parameterString.urlEncodedString
let encodedURL = url.absoluteString.urlEncodedString
let signatureBaseString = "\(method.rawValue)&\(encodedURL)&\(encodedParameterString)"
let key = signingKey.data(using: .utf8)!
let msg = signatureBaseString.data(using: .utf8)!
let sha1 = msg.hmac(key: key)
return sha1.base64EncodedString(options: [])
}