我正在使用Google的GTMOAuth for iOS/Mac SDK以便能夠連接API,如API API和Instagram API。它一切正常,但是當用戶進行身份驗證時,我只能獲取訪問令牌。這一切都很好,但過了一段時間,訪問令牌失效,用戶不得不重新登錄,這很糟糕。GTM OAuth不下載刷新令牌 - iOS
我的問題是,當用戶進行身份驗證,我只得到回一個訪問令牌,並沒有別的...
感謝你的幫助:)
我正在使用Google的GTMOAuth for iOS/Mac SDK以便能夠連接API,如API API和Instagram API。它一切正常,但是當用戶進行身份驗證時,我只能獲取訪問令牌。這一切都很好,但過了一段時間,訪問令牌失效,用戶不得不重新登錄,這很糟糕。GTM OAuth不下載刷新令牌 - iOS
我的問題是,當用戶進行身份驗證,我只得到回一個訪問令牌,並沒有別的...
感謝你的幫助:)
可能是這樣一個對您有幫助.. !
我正在使用Google oauth 2.0進行谷歌驅動器身份驗證。
在Google完成身份驗證方法中,像這樣在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];
}
}
之後當過您要使用的存取權限令牌用於執行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
而且記住這一點。對於Google等一些API,如果您希望它爲您提供刷新令牌,則需要添加「approval_prompt = force」和「access_type = offline」。爲了添加這些參數,你必須編輯GTMOAuth2SignIn.m文件並替換「paramsDict」這個的NSMutableDictionary:
NSMutableDictionary *paramsDict = [NSMutableDictionary dictionaryWithObjectsAndKeys:
@"code", @"response_type",
clientID, @"client_id",
scope, @"scope", // scope may be nil
@"force", @"approval_prompt",
@"offline", @"access_type",
nil];
您還可以使用GTMOAuth2Authentication的authorizeRequest: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
}
}];
令牌將被刷新,你可以繼續查詢。
非常感謝你的回答。它在理解邏輯方面真的幫了我很大的忙。但是我仍然有一個問題。做「self.auth.refreshToken」返回null ....當我試圖下載訪問令牌「self.auth.accessToken」時,它的工作原理。那麼,爲什麼它不下載任何刷新標誌? – Supertecnoboff
我沒有給你。可以請給我解釋一下,所以也許我可以幫助你。 –
所以基本上你知道名爲「finishedWithAuth」的方法,你可以通過執行以下操作獲得accessToken和refreshToken的副本:「self.auth.accessToken」和「self.auth.refreshToken」。那麼基本上,當我做「self.auth.accessToken」我可以得到一個accessToken的副本。但是,當我嘗試做「NSString * refresh = self.auth.refreshToken」我無法獲取刷新標記,因爲刷新標記爲空..... ????? – Supertecnoboff