GTM Oauth不会下载刷新令牌-IOS



我正在为iOS/Mac SDK使用Google的GTMOAUTH,以便能够与API(例如YouTube API和Instagram API)连接。一切都很好,但是当用户身份验证时,我只能获得访问令牌。这一切都很好,但是过了一会儿,访问令牌就到期了,用户必须重新使用这很糟糕。

我的问题是,当用户身份验证时,我只会恢复一个访问令牌,而没有其他...

感谢您的帮助:)

可能会帮助您..!

我正在使用Google Oauth 2.0,用于Google Drive身份验证。

在Google中使用身份验证方法完成了访问和刷新令牌的值

 - (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调用时,首先使用现有的accessToken值从NSUSERDEFAULTS进行调用,然后在URL响应中检查状态代码。如果您获得状态代码'401'意味着您的访问令牌已过期,则无效。然后,您必须使用像这样的nsuserdefaults中使用保存的刷新令牌值请求刷新令牌。

这是您的第一个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];
        } 
    }

这是为了从刷新令牌请求新访问。

-(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。

- (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,您需要添加" Apploval_prompt = force"one_answers" Access_Type = offline",如果您希望它为您提供刷新令牌。为了添加这些参数,您必须编辑gtmoauth2signin.m文件,然后用此nsmutabledictionary替换" paramsdict":

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

您也可以使用 gtmoauth2authentication 's authorizeRequest:completionHandler:方法

如果您的应用程序将授权保存到键链(通过设置控制器的键Chainitemname),则可以在应用程序启动时检索:

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
                 }
             }];

随后将刷新令牌,您可以继续进行查询。

最新更新