GTM OAuth不下载刷新令牌 – iOS

我正在使用Google的GTMOAuth for iOS / Mac SDK,以便能够连接诸如YouTube API和Instagram API之类的APIS。 这一切工作正常,但是当用户身份validation,我只能得到访问令牌。 这一切都很好,但过了一段时间访问令牌到期,用户不得不重新login这是可怕的。

我的问题是,当用户身份validation,我只能得到一个访问令牌,没有别的…

感谢您的帮助:)

可能是这个帮助你..!

我正在使用谷歌oauth 2.0,谷歌驱动器身份validation。

在Google完成身份validation方法中,像这样在NSUSerDefaults中保存accesstoken和刷新标记值。

- (void)viewController:(GTMOAuth2ViewControllerTouch *)viewController finishedWithAuth:(GTMOAuth2Authentication *)authResult error:(NSError *)error { if (error != nil) { [self showAlert:@"Authentication Error" message:error.localizedDescription]; self.driveService.authorizer = nil; } else { self.driveService.authorizer = authResult; self.auth = authResult; NSLog(@"\n accessToken value is %@",self.auth.accessToken); [[NSUserDefaults standardUserDefaults] setValue:self.auth.refreshToken forKey:@"refreshToken"]; [[NSUserDefaults standardUserDefaults] setValue:self.auth.accessToken forKey:@"accessToken"]; [[NSUserDefaults standardUserDefaults] synchronize]; } } 

之后,当您想要使用acces令牌执行api调用时,首先使用NSUSERDefaults中现有的accesstoken值进行调用,然后在url响应中检查状态代码。 如果您获得状态码“401”,则表示您的访问令牌已过期,无效。 然后,你必须使用NSUserDefaults中保存的刷新标记值来请求刷新标记。

这是您第一次检查accesstoken有效与否的API调用。

  - (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse *)response { NSLog(@"Did Receive Response %@", response); NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response; //int responseStatusCode = [httpResponse statusCode]; if (httpResponse.statusCode == 200) { //Your api call success and accesstoken is valid. } else if(httpResponse.statusCode == 401 && connection == self.conn2) { [[self appDelegate] refreshAccessToken]; } } 

这是从刷新令牌请求新的accesstoken。

 -(void)refreshAccessToken { NSString *requestString = [NSString stringWithFormat:@"https://accounts.google.com/o/oauth2/token"]; NSString *string = [NSString stringWithFormat:@"client_id=%@&client_secret=%@&refresh_token=%@&grant_type=refresh_token",kClientID,kClientSecret,[[NSUserDefaults standardUserDefaults] valueForKey:@"refreshToken"]]; NSData *postData = [string dataUsingEncoding:NSUTF8StringEncoding]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:requestString]]; NSLog(@"\n request str : %@",request); NSLog(@"\n refresh token value is %@",[[NSUserDefaults standardUserDefaults] valueForKey:@"refreshToken"]); [request setHTTPMethod:@"POST"]; [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"]; [request setHTTPBody:postData]; NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];//connectionWithRequest:request delegate:self]; if(connection) { NSLog(@"Connection Successful"); } else { NSLog(@"Connection could not be made"); } [connection start]; } 

作为响应,再次检查状态码,如果状态码是200,则更新userdafaults中的值。

 - (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse *)response { NSLog(@"Did Receive Response %@", response); //NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response; self.data = [NSMutableData data]; } - (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data { NSLog(@"Did Receive Data %@", data); [self.data appendData:data]; } - (void)connection:(NSURLConnection*)connection didFailWithError:(NSError*)error { NSLog(@"Did Fail %@",error); } - (void)connectionDidFinishLoading:(NSURLConnection *)connection { NSLog(@"Did Finish"); // Do something with responseData NSError *err; id JSon = [NSJSONSerialization JSONObjectWithData:self.data options:kNilOptions error:&err]; if (err) { NSLog(@"%@",err); } else { NSLog(@"Json %@",JSon); [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"accessToken"]; [[NSUserDefaults standardUserDefaults] setObject:[JSon valueForKey:@"access_token"] forKey:@"accessToken"]; [[NSUserDefaults standardUserDefaults] synchronize]; } } 

这是我在堆栈溢出的第一个答案。 对不起,有任何错误。

下面的更新 – 由Supertecnoboff写

也请记住这一点。 对于一些API,比如Google,如果你想给它一个刷新标记,你需要添加“approval_prompt = force”和“access_type = offline”。 为了添加这些参数,你必须编辑GTMOAuth2SignIn.m文件并用这个NSMutableDictionaryreplace“paramsDict”:

 NSMutableDictionary *paramsDict = [NSMutableDictionary dictionaryWithObjectsAndKeys: @"code", @"response_type", clientID, @"client_id", scope, @"scope", // scope may be nil @"force", @"approval_prompt", @"offline", @"access_type", nil]; 

您也可以使用GTMOAuth2AuthenticationauthorizeRequest:completionHandler:方法

如果您的应用程序将授权保存到钥匙串(通过设置控制器的keychainItemName),则可以在下次启动应用程序时检索它:

 GTMOAuth2Authentication *auth = [GTMOAuth2ViewControllerTouch authForGoogleFromKeychainForName:kKeychainItemName clientID:kClientID clientSecret:kClientSecret]; NSLog(@"accessToken: %@", auth.accessToken); //If the token is expired, this will be nil 

然后你可以像这样刷新访问令牌:

 // authorizeRequest will refresh the token, even though the NSURLRequest passed is nil [auth authorizeRequest:nil completionHandler:^(NSError *error) { if (error) { NSLog(@"error: %@", error); } else { NSLog(@"accessToken: %@", auth.accessToken); //it shouldn´t be nil } }]; 

令牌将被刷新,您可以继续查询。