问题
I've set up the GPPSignInButton based on the following:
https://developers.google.com/+/mobile/ios/sign-in#enable_server-side_api_access_for_your_app
let googleSignIn = GPPSignIn.sharedInstance()
googleSignIn.clientID = GoogleClientID
googleSignIn.attemptSSO = true
googleSignIn.homeServerClientID = GoogleServerClientID
googleSignIn.scopes = ["https://www.googleapis.com/auth/plus.login", "https://www.googleapis.com/auth/plus.profile.emails.read"]
googleSignIn.delegate = self
googleSignInButton.colorScheme = kGPPSignInButtonColorSchemeLight
googleSignInButton.style = kGPPSignInButtonStyleWide
When the user signs in the first time it asks for the correct permissions and returns the idToken which gets forwarded to the server and exchanged for an access_token/refresh_token.
However after calling GPPSignIn.sharedInstance().signOut(), signing in again will always ask for the "Have offline access" permission.
I've read through some of the other SO posts referencing this and most of them reference URL parameters "approval_prompt" and "access_type". Given that I'm using the iOS SDK, I don't have the ability to set these parameters.
The url that the app routes to in the web view is:
https://accounts.google.com/o/oauth2/auth?gpsdk=1.7.1&audience=<server-client-id>&response_type=code&verifier=94014002&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fplus.login%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fplus.profile.emails.read&gpbtn=1.1&hl=en&redirect_uri=<redirect_uri>&client_id=<client-id>&state=702574
I have the same scopes ("login" and "email") on the server side, I can't figure out what else I need to do so it doesn't always ask for permission to have offline access.
回答1:
I understand that you are using Google's iOS SDK.
What you are talking is the default behaviour of Google API.
Using below solution you can add "approval_prompt=force" and "access_type=offline" parameters to the URL.
Solution:
So as to add these parameters, you will have to modify GTMOAuth2SignIn.m and replace the "paramsDict" with following NSMutableDictionary:
NSMutableDictionary *paramsDict = [NSMutableDictionary dictionaryWithObjectsAndKeys:
@"code", @"response_type",
clientID, @"client_id",
scope, @"scope",
@"force", @"approval_prompt",
@"offline", @"access_type",
nil];
I am sure after this your issue will be resolved.
Update:
For GPPSignin class usage you should check whether trySilentAuthentication is possible. this api checks if the Signin is possible without user interaction.
Explanation about trySilentAuthentication
When you call authenticate, sdk saves a long lived token in the keychain for the user, as well as a short lived token for making API calls. Calling trySilentAuthentication checks whether the long lived token is in the key chain, and generates a new short lived token. If it succeeds it means the user has signed in to that app on that device before, so you generally will want to respond to that appropriately. If it fails (there is no token) it will just return false, or if it can't generate a short lived token it will call finishedWithAuth:error with the error set.
来源:https://stackoverflow.com/questions/28594030/ios-gppsigninbutton-always-asks-for-have-offline-access-permission