GTM OAuth не скачивает токен обновления - iOS

Я использую Google GTMOAuth для iOS/Mac SDK, чтобы иметь возможность подключаться к APIS, таким как YouTube API и Instagram API. Все работает нормально, однако, когда пользователь проходит аутентификацию, я могу получить только токен доступа. Это все хорошо, но через некоторое время токены доступа истекают, и пользователь должен повторно войти в систему, что ужасно.

Моя проблема в том, что когда пользователь проходит аутентификацию, я ТОЛЬКО возвращаю токен доступа и ничего больше...

Спасибо за помощь:)

2 ответа

Решение

Может быть, это поможет вам..!

Я использую Google OAUT 2.0, для аутентификации Google Drive.

В Google закончили с методом аутентификации, сохраните токен доступа и обновите значения токена в NSUSerDefaults, как это.

 - (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, сначала сделайте вызов, используя существующее значение 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. Затем обновите значение в 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, вам нужно добавить "compatibility_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];

Вы также можете использовать 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
                 }
             }];

Затем токен будет обновлен, и вы сможете продолжать делать запросы.

Другие вопросы по тегам