init(clientID : String, authorizationEndpoint : URL, tokenEndpoint : URL, keychain: Keychain)
convenience init(clientID : String, authorizationEndpoint : URL, tokenEndpoint : URL, keychain: Keychain, scopes: String)
Availability
Framework
class DeviceAuthorizationFlow
As per the IETF: “The OAuth 2.0 device authorization grant is designed for Internet-connected devices that either lack a browser to perform a user-agent-based authorization or are input constrained to the extent that requiring the user to input text in order to authenticate during the authorization flow is impractical.” So, this authorization flow is particularly useful for tvOS and perhaps watchOS as well.
Conforms to the Swauthable
protocol.
See init(client
and/or init(client
for initialization examples.
To use the Device Authorization Grant Flow, first create an instance of Keychain and then create an instance of DeviceAuthorizationFlow by filling in the information of the Web API you wish to utilize. Google’s TV authentication will be used as an example.
let keychain = Keychain(service: "com.your.bundleID",
accessGroup: "appIdentifierPrefix.com.your.bundleID").label("Your App Name")
let googleTV = DeviceAuthorizationFlow(clientID: "YourClientID",
authorizationEndpoint: URL(string: "https://oauth2.googleapis.com/device/code")!,
tokenEndpoint: URL(string: "https://oauth2.googleapis.com/device/code")!,
keychain: keychain
scopes: "email provider")
// Google's device flow specifically requires additional parameters:
googleTV.additionalTokenRequestParams = ["client_secret": "YourClientSecret"]
googleTV.additionalRefreshTokenBodyParams = ["client_id": "YourClientID", "client_secret": "YourClientSecret"]
Now send the authorization request and handle the response:
let deviceAuthReq = try await googleTV.deviceFlowAuthorizationRequest()
try await googleTV.authorizationResponseHandler(for: deviceAuthReq)
Obviously, you will need to display the authorization code and URL to the user. See Device
for more information.
Assuming no errors were thrown, you can now successfully make an authorized HTTP request to the endpoint of your choice and print the resulting JSON:
let request = HTTPRequest(endpoint: URL(string: "https://openidconnect.googleapis.com/v1/userinfo")!)
let response = try await googleTV.authenticatedRequest(for: request)
// Assuming no errors were thrown
print(response.json())
init(clientID : String, authorizationEndpoint : URL, tokenEndpoint : URL, keychain: Keychain)
convenience init(clientID : String, authorizationEndpoint : URL, tokenEndpoint : URL, keychain: Keychain, scopes: String)
var additionalAuthorizationParams : [String : String]?
var additionalTokenRequestParams : [String : String]?
var additionalRefreshTokenBodyParams : [String : String]?
authenticatedRequest(for:numberOfRetries:)
is made.var scopes: String?
var authHeaderTokenType : String?
func deviceFlowAuthorizationRequest () async throws -> DeviceAuthorizationFlow .DeviceAuthResponse
DeviceAuthorizationFlow.DeviceAuthResponse
instance.func authorizationResponseHandler (for: Response) async throws
DeviceAuthorizationFlow.DeviceAuthResponse
Response
from a call to deviceFlowAuthorizationRequest()
. Sends a HTTP request to the initialized token endpoint for the tokens. Polling will only happen for 15 minutes.struct DeviceAuthResponse
deviceFlowAuthorizationRequest()
method. Used as the parameter in the authorizationResponseHandler(for:)
method.var authorizationParams : [String : String]
var tokenRequestParams : [String : String]
let authorizationEndpoint : URL
let clientID : String
let keychain: Keychain
let tokenEndpoint : URL
class AuthorizationCodeFlow
class PKCEAuthorizationFlow