To run the example project, clone the repo, and run pod install
from the Example directory first.
Swift 4, 4.2 or 5. The pure-Swift subspec has no dependencies.
TDOAuth is available through CocoaPods. To install it, simply add the following line to your Podfile:
pod 'TDOAuth'
Add .package(url: "https://github.com/yahoo/TDOAuth.git", from: "1.6.0")
to your package.swift
The two legs of two-legged OAuth are the client and server. This method of authentication is suitable for verifying access from a blessed first-party. If you have only a consumer secret and consumer key, this the method you would use:
let consumerSecret = "my-consumer-secret"
let consumerKey = "my-consmer-key"
/// Generate our OAuth1 signer
let oauth1: OAuth1<HMACSigner> = {
let secrets = SharedSecrets(consumerSecret: consumerSecret)
let sha1Signer = HMACSigner(algorithm: .sha1, material: secrets)
return OAuth1(withConsumerKey: consumerKey, signer: sha1Signer)
}()
/// Feed requests into our OAuth1 signer to produce signed versions of those requests.
/// The only modificataion to the provided request is setting the Authorization HTTP header.
func signRequest(_ request: URLRequest) -> URLRequest? {
return oauth1.sign(request: request)
}
Three-legged OAuth is a version suitable for authenticating a third-party to access a user's data. This method introduces a second set of key & secret for the third party:
let consumerSecret = "my-consumer-secret"
let consumerKey = "my-consmer-key"
let accessToken: String? = "access-token"
let accessTokenSecret: String? = "token-secret"
/// Generate our OAuth1 signer
let oauth1: OAuth1<HMACSigner> = {
let secrets = SharedSecrets(consumerSecret: consumerSecret, accessTokenSecret: accessTokenSecret)
let sha1Signer = HMACSigner(algorithm: .sha1, material: secrets)
return OAuth1(withConsumerKey: consumerKey, accessToken: accessToken, signer: sha1Signer)
}()
/// Feed requests into our OAuth1 signer to produce signed versions of those requests.
/// The only modificataion to the provided request is setting the Authorization HTTP header.
func signRequest(_ request: URLRequest) -> URLRequest? {
return oauth1.sign(request: request)
}
In the examples above, we use SHA-1 HMAC to sign generate the signatures. You may want to use a more secure hashing algorithm since SHA-1 is quite weak now. TDOAuth supports more secure SHA-2 signing by default, as well as arbitrary signing (Bring Your Own Algorithm).
Supported SHA-2 variants:
- SHA-224
- SHA-256
- SHA-384
- SHA-512
Example for SHA-256
let signer: OAuth1<HMACSigner> = HMACSigner(algorithm: .sha256, material: secrets)
Plain text signing is useful mainly for debugging or use over strictly pinned SSL connections. The keys are not secured in any way, so it is very bad idea to use this strategy without pinned SSL.
Example for PlainText signing
let signer: OAuth1<PlaintextSigner> = PlaintextSigner(keyMaterial: secrets)
To provide your own custom signing, implement the OAuth1Signer
protocol:
public protocol OAuth1Signer {
associatedtype KeyMaterial
var signatureMethod: String { get }
init(keyMaterial: KeyMaterial)
func sign(_ value: String) -> String
}
For a simple example, see the implementation in PlaintextSigner.swift
.
Using the Objective-C API is not recommended. It is provided for backwards compatability with the old TDOAuth Obj-C API. While the underlying code uses the exact same Swift code as above, the legacy TDOAuth API imposed significant opinions on the requests, and those opinions were replicated in the new compatability API. For example, a User-Agent header is generated and added automatically to your request. Handling for POST and form-data has a lot of caveats and edge cases around encoding.
While the Swift API simply signs whatever URLRequest
you provide it, the Objective-C API generates a new NSURLRequest
for you as part of the signing process. As a result you may need to carefully alter the returned request instance to suit your needs (be sure not to break the signature).
Use the Swift API!
Objective-C API Example
@import TDOAuth;
NSURLRequest * request = [TDOAuth URLRequestForPath:@"/v1/service/name"
parameters:@{ "count": @10, "format": "json" }
host:@"api.example.com"
consumerKey:@"my-consumer-key"
consumerSecret:@"my-consumer-secret"
accessToken:@"my-token"
tokenSecret:@"my-token-secret"
scheme:@"https"
requestMethod:@"GET"
dataEncoding:TDOAuthContentTypeUrlEncodedForm
headerValues:@{ "Accept": "application/json" }
signatureMethod:TDOAuthSignatureMethodHmacSha1;
Adam Kaplan, [email protected]
TDOAuth is available under the MIT license. See the LICENSE file for more info.