Swift implementation of RFC 6750: The OAuth 2.0 Authorization Framework - Bearer Token Usage.
RFC 6750 defines how to use Bearer tokens in HTTP requests to access OAuth 2.0 protected resources. This package provides a pure Swift implementation of Bearer token handling, including all three transmission methods (Authorization header, form parameters, and query parameters), WWW-Authenticate challenge generation and parsing, and comprehensive error handling according to the RFC 6750 specification.
- RFC Compliant: Full implementation of RFC 6750 Bearer Token specification
- Three Transmission Methods: Support for Authorization header (recommended), form parameters, and query parameters
- WWW-Authenticate Challenges: Generation and parsing of authentication challenges
- Error Handling: Complete OAuth 2.0 error codes (invalid_request, invalid_token, insufficient_scope)
- Type-Safe: Validated token creation with proper error handling
- Sendable: Full Swift 6 concurrency support
- Zero Dependencies: Pure Swift implementation
Add swift-rfc-6750 to your package dependencies:
dependencies: [
.package(url: "https://github.com/swift-standards/swift-rfc-6750.git", from: "0.1.0")
]Then add it to your target:
.target(
name: "YourTarget",
dependencies: [
.product(name: "RFC_6750", package: "swift-rfc-6750")
]
)import RFC_6750
// Create a Bearer token
let bearer = try RFC_6750.Bearer(token: "mF_9.B5f-4.1JqM")
// Use in Authorization header (recommended method)
let headerValue = bearer.authorizationHeaderValue()
// Result: "Bearer mF_9.B5f-4.1JqM"// Parse from Authorization header
let authHeader = "Bearer mF_9.B5f-4.1JqM"
let bearer = try RFC_6750.Bearer.parse(from: authHeader)
print(bearer.token) // "mF_9.B5f-4.1JqM"
// Parse from form parameters
let formParams = ["access_token": "mF_9.B5f-4.1JqM"]
let bearerFromForm = try RFC_6750.Bearer.parse(fromFormParameters: formParams)
// Parse from query parameters
let queryItems = [URLQueryItem(name: "access_token", value: "mF_9.B5f-4.1JqM")]
let bearerFromQuery = try RFC_6750.Bearer.parse(fromQueryItems: queryItems)// Create a challenge with error information
let challenge = RFC_6750.Bearer.Challenge(
realm: "example",
scope: "read write",
error: .invalidToken,
errorDescription: "The access token expired"
)
// Generate WWW-Authenticate header value
let headerValue = challenge.wwwAuthenticateHeaderValue()
// Result: Bearer, realm="example", scope="read write", error="invalid_token", error_description="The access token expired"let wwwAuth = "Bearer, realm=\"example\", error=\"invalid_token\""
let challenge = try RFC_6750.Bearer.Challenge.parse(from: wwwAuth)
print(challenge.realm) // Optional("example")
print(challenge.error) // Optional(RFC_6750.Bearer.ErrorCode.invalidToken)// Token validation errors
do {
let bearer = try RFC_6750.Bearer(token: "")
} catch RFC_6750.Bearer.Error.invalidToken(let message) {
print("Token error: \(message)")
}
// Parse errors
do {
let bearer = try RFC_6750.Bearer.parse(from: "Invalid header")
} catch RFC_6750.Bearer.Error.invalidRequest(let message) {
print("Request error: \(message)")
}
// Using error codes
let error = RFC_6750.Bearer.Error.insufficientScope("Requires admin access")
print(error.errorCode) // ErrorCode.insufficientScope
print(error.localizedDescription) // "Insufficient scope: Requires admin access"public struct Bearer: Codable, Hashable, Sendable {
public let token: String
init(token: String) throws
}// Authorization header (recommended)
func authorizationHeaderValue() -> String
// Form parameters
func formParameter() -> (name: String, value: String)
// Query parameters (not recommended for security reasons)
func queryParameter() -> (name: String, value: String)public struct Challenge: Codable, Hashable, Sendable {
public let realm: String?
public let scope: String?
public let error: ErrorCode?
public let errorDescription: String?
func wwwAuthenticateHeaderValue() -> String
static func parse(from headerValue: String) throws -> Challenge
}public enum ErrorCode: String, CaseIterable {
case invalidRequest = "invalid_request"
case invalidToken = "invalid_token"
case insufficientScope = "insufficient_scope"
}public enum Error: Swift.Error {
case invalidRequest(String)
case invalidToken(String)
case insufficientScope(String)
var errorCode: ErrorCode { get }
var localizedDescription: String { get }
}- None - This is a pure Swift implementation
- Swift 6.0+
- macOS 13.0+ / iOS 16.0+ / tvOS 16.0+ / watchOS 9.0+
This library is released under the Apache License 2.0. See LICENSE for details.
Contributions are welcome! Please feel free to submit a Pull Request.