init(clientID : String, authorizationEndpoint : URL, tokenEndpoint : URL, keychain: Keychain) convenience init(clientID : String, authorizationEndpoint : URL, tokenEndpoint : URL, keychain: Keychain, scopes: String) Availability
Framework
class DeviceAuthorizationFlowAs 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