Reputation: 3221
I'm using the AppAuth library to get an access token for the Gmail API. I've successfully been able to create an Auth Session, and use the retrieved token to later fetch the emails.
In my AppDelegate
I have two variables:
var currentAuthorizationFlow: OIDExternalUserAgentSession?
var authState: OIDAuthState?
In my SignInViewController
, I have the following code for performing the authorization flow:
@objc func startAuthFlow() {
Analytics.logEvent("auth_started", parameters: nil)
let authorizationEndpoint = URL(string: "https://accounts.google.com/o/oauth2/v2/auth")!
let tokenEndpoint = URL(string: "https://www.googleapis.com/oauth2/v4/token")!
let configuration = OIDServiceConfiguration(authorizationEndpoint: authorizationEndpoint,
tokenEndpoint: tokenEndpoint)
let kRedirectURI: String = "com.googleusercontent.apps.someNumber:/oauthredirect";
guard let redirectURI = URL(string: kRedirectURI) else {
return
}
let appDelegate = UIApplication.shared.delegate as! AppDelegate
// builds authentication request
let request = OIDAuthorizationRequest(configuration: configuration,
clientId: "myID",
clientSecret: nil,
scopes: ["https://mail.google.com/"],
redirectURL: redirectURI,
responseType: OIDResponseTypeCode,
additionalParameters: nil)
// performs authentication request
print("Initiating authorization request with scope: \(request.scope ?? "nil")")
appDelegate.currentAuthorizationFlow =
OIDAuthState.authState(byPresenting: request, presenting: self) { authState, error in
if let authState = authState {
print("Got authorization tokens. Access token: " +
"\(authState.lastTokenResponse?.accessToken ?? "nil")")
A0SimpleKeychain().setString((authState.lastTokenResponse?.accessToken)!, forKey: "auth0-user-jwt")
A0SimpleKeychain().setString((authState.lastTokenResponse?.refreshToken)!, forKey: "auth0-user-jwt-refresh")
EmailFetcher.shared.setupEmailSession(token: (authState.lastTokenResponse?.accessToken)!)
} else {
print("Authorization error: \(error?.localizedDescription ?? "Unknown error")")
}
}
}
I then successfully save the token and the refresh token.
I saw that there was a tokenRefreshRequest()
method for OIDAuthState
, but my understanding is that you would need to pass in the refresh token to get a new, fresh token, correct? What's the missing piece to implementing this with AppAuth?
Upvotes: 5
Views: 4196
Reputation: 253
Create an authState from auth token or directly save authstate model into key chain then access latest refresh token using below methods. authState
authState.performAction { (accessToken, authToken, error) in
guard let err = error else {return}
print("updated refresh token is : \(accessToken)")
}
Upvotes: 1
Reputation: 29243
To refresh an access token you use a 'refresh token grant' message with arguments similar to this:
let request = OIDTokenRequest(
configuration: self.metadata!,
grantType: OIDGrantTypeRefreshToken,
authorizationCode: nil,
redirectURL: nil,
clientID: self.configuration.clientId,
clientSecret: nil,
scope: nil,
refreshToken: tokenData!.refreshToken!,
codeVerifier: nil,
additionalParameters: nil)
OIDAuthorizationService.perform(request) { tokenResponse, error in ...
Note that I'm not using the AuthState class in my sample, since I wanted to store tokens encrypted in the iOS keychain, so your code may be a little different. For something to compare against, you can run the code sample from by blog:
Upvotes: 4