OhhAuth

OAuth 1.0 协议的纯 Swift 实现,作为 URLRequest 类型的易于使用的扩展。(RFC-5849)

即使其后续版本已经指定,OAuth 1.0 协议仍然被广泛使用。此易于使用的 URLRequest 类型扩展实现了最常见的 OAuth 客户端请求变体。

要求

更新后的 OhhAuth 依赖于 swift-crypto,它已安装在所有常见的 Apple 操作系统(macOS 10.15、iOS 13、tvOS 13、watchOS 6)上。 这也增加了对 Linux 的支持。

使用示例

典型的使用示例是在 Twitter 上发布推文

要获得消费者凭证(密钥和秘钥),您首先必须在 https://apps.twitter.com 注册一个新的 Twitter 应用程序

有很多方法可以获取用户凭据(例如 OAuth 反向身份验证),但对于测试来说,最简单的方法是直接从您的 Twitter 应用程序页面,使用 本指南

有关 api.twitter.com/1.1/statuses/update.json 的更多信息,请参阅 Twitter API 文档

let cc = (key: "<YOUR APP CONSUMER KEY>", secret: "<YOUR APP CONSUMER SECRET>")
let uc = (key: "<YOUR USER KEY>", secret: "<YOUR USER SECRET>")

var req = URLRequest(url: URL(string: "https://api.twitter.com/1.1/statuses/update.json")!)

let paras = ["status": "Hey Twitter! \u{1F6A7} Take a look at this sweet UUID: \(UUID())"]

req.oAuthSign(method: "POST", urlFormParameters: paras, consumerCredentials: cc, userCredentials: uc)

let task = URLSession(configuration: .ephemeral).dataTask(with: req) { (data, response, error) in
    
    if let error = error {
        print(error)
    }
    else if let data = data {
        print(String(data: data, encoding: .utf8) ?? "Does not look like a utf8 response :(")
    }
}
task.resume()

安装

Cocoa Pods

要使用 CocoaPods 将 OhhAuth 集成到您的 Xcode 项目中,请将其添加到您的 Podfile

target '<your_target_name>' do
    pod 'OhhAuth'
end

然后,运行以下命令

$ pod install

然后,您需要在 swift 源文件的顶部添加 import OhhAuth 才能使用该扩展。

Swift Package Manager

要使用 Swift Package Manager 将 OhhAuth 集成到您的 Xcode 项目中,请将其作为依赖项添加到您的 Package.swift 文件中

import PackageDescription

let package = Package(
    name: "<your_package_name>",
    dependencies: [
        .Package(url: "https://github.com/mw99/OhhAuth.git", majorVersion: 1)
    ]
)

然后,您需要在 swift 源文件的顶部添加 import OhhAuth 才能使用该扩展。

或者直接将文件复制到您的项目中

您只需要一个位于 Sources/OhhAuth.swift 的文件。 只需将其拖放到 Xcode 项目导航器中即可。

接口

作为 URLRequest 扩展
/// Easy to use method to sign a URLRequest which includes url-form parameters with OAuth.
/// The request needs a valid URL with all query parameters etc. included.
/// After calling this method the HTTP header fields: "Authorization", "Content-Type" 
/// and "Content-Length" should not be overwritten.
///
/// - Parameters:
///   - method: HTTP Method
///   - paras: url-form parameters
///   - consumerCredentials: consumer credentials
///   - userCredentials: user credentials (nil if this is a request without user association)
public mutating func oAuthSign(method: String, urlFormParameters paras: [String: String],
    consumerCredentials cc: OhhAuth.Credentials, userCredentials uc: OhhAuth.Credentials? = nil)
/// Easy to use method to sign a URLRequest which includes plain body data with OAuth.
/// The request needs a valid URL with all query parameters etc. included.
/// After calling this method the HTTP header fields: "Authorization", "Content-Type"
/// and "Content-Length" should not be overwritten.
///
/// - Parameters:
///   - method: HTTP Method
///   - body: HTTP request body (default: nil)
///   - contentType: HTTP header "Content-Type" entry (default: nil)
///   - consumerCredentials: consumer credentials
///   - userCredentials: user credentials (nil if this is a request without user association)
public mutating func oAuthSign(method: String, body: Data? = nil, contentType: String? = nil,
    consumerCredentials cc: OhhAuth.Credentials, userCredentials uc: OhhAuth.Credentials? = nil)
class OhhAuth 直接访问
/// Function to calculate the OAuth protocol parameters and signature ready to be added
/// as the HTTP header "Authorization" entry. A detailed explanation of the procedure 
/// can be found at: [RFC-5849 Section 3](https://tools.ietf.org/html/rfc5849#section-3)
///
/// - Parameters:
///   - url: Request url (with all query parameters etc.)
///   - method: HTTP method
///   - parameter: url-form parameters
///   - consumerCredentials: consumer credentials
///   - userCredentials: user credentials (nil if this is a request without user association)
///
/// - Returns: OAuth HTTP header entry for the Authorization field.
open static func calculateSignature(url: URL, method: String, parameter: [String: String],
    consumerCredentials cc: Credentials, userCredentials uc: Credentials?) -> String
/// Function to perform the right percentage encoding for url form parameters.
///
/// - Parameter paras: url-form parameters
/// - Parameter encoding: used string encoding (default: .utf8)
/// - Returns: correctly percentage encoded url-form parameters
open static func httpBody(forFormParameters paras: [String: String], 
    encoding: String.Encoding = .utf8) -> Data?