How to keep browser from showing sign in screen on every launch?
Nobody has claimed this yet.
- Dominant language
- Objective-C
- Stars
- 2k
- Forks
- 867
- Avg merge
- 4d 48m
- Merged PRs (30d)
- 1
Description
Hello, I'm using AppAuth on macOS (11.2.3) in a native Swift application and it works in terms of logging into Google and using the APIs. However, every time I launch the app, it asks me to re-authenticate in the browser (in this case Safari, but I have tried it with Chrome as well), even if I just used it minutes ago. I'm using it only with a single Google account on a single machine.
Is there a way I should be using a stored refresh token on the next launch to tell AppAuth to bypass the browser authentication and just use the saved token (if it's still valid)? I can save it in NSUserDefaults and/or iCloud Keychain but I don't know how to tell AppAuth about it.
Code that I call when app launches:
func authorizeGoogleAccount() -> Bool {
let dg = DispatchGroup()
dg.enter()
let serverPort: UInt16 = 62626
let issuer = URL(string: "https://accounts.google.com")!
// discovers endpoints
OIDAuthorizationService.discoverConfiguration(forIssuer: issuer) { configuration, error in
guard let config = configuration else {
print("Error retrieving discovery document: \(error?.localizedDescription ?? "Unknown error")")
return
}
let kSuccessUrlString = "http://openid.github.io/AppAuth-iOS/redirect/"
let url = URL(string: kSuccessUrlString)
// Starts a loopback HTTP redirect listener to receive the code. This needs to be started first,
// as the exact redirect URI (including port) must be passed in the authorization request.
self.redirectHandler = OIDRedirectHTTPHandler(successURL: url)
let errPtr = NSErrorPointer(nilLiteral: ())
guard let redirectUri = self.redirectHandler?.startHTTPListener(errPtr, withPort: serverPort) else {
print("Failed to start HTTP auth listener.")
return
}
// Configure the auth request.
let request = OIDAuthorizationRequest(configuration: config, clientId: kGoogleClientID, clientSecret: kGoogleClientSecret, scopes: [kGoogleDriveAuthScope, kGoogleMailAuthScope], redirectURL: redirectUri, responseType: OIDResponseTypeCode, additionalParameters: nil)
// Perform the auth request.
self.redirectHandler?.currentAuthorizationFlow = OIDAuthState.authState(byPresenting: request) { authState, error in
NSRunningApplication.current.activate(options: [.activateAllWindows, .activateIgnoringOtherApps])
if let noptAuthState = authState, let token = noptAuthState.lastTokenResponse?.accessToken {
self.googleAuthState = noptAuthState
self.googleAuthAccessToken = token
print("Google auth access token = \(token)")
if let refreshToken = noptAuthState.lastTokenResponse?.refreshToken {
self.googleAuthRefreshToken = refreshToken
print("Google auth refresh token = \(refreshToken)")
kKeychain.set(refreshToken, forKey: kGoogleKeychainItemName, withAccess: .accessibleAfterFirstUnlockThisDeviceOnly)
} else {
print("No refresh token returned.")
_ = self.freshGoogleAccessToken()
}
} else {
print("Auth error = \(error?.localizedDescription ?? "<nil>")")
}
dg.leave()
}
}
dg.wait()
return self.googleAuthAccessToken != nil
}
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with authorizeGoogleAccount and the OIDAuthState.authState(byPresenting:) call, then inspect how googleAuthRefreshToken is stored and used by freshGoogleAccessToken. Done means establishing whether the saved refresh token is used during launch and documenting or correcting the flow so unnecessary browser authentication is avoided.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- swift
- Domain
- authentication, desktop-dev
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 22/100