【问题标题】:Using refresh access token gives "Request failed: unauthorized (401)"使用刷新访问令牌给出“请求失败:未经授权 (401)”
【发布时间】:2015-02-22 12:38:16
【问题描述】:

我在谷歌日历 api 工作。

以下是用于创建日历的代码

if([self.auth shouldRefreshAccessToken]) {
    self.auth.accessToken=self.auth.refreshToken;
}

NSString *strURL=[NSString stringWithFormat:@"https://www.googleapis.com/calendar/v3/calendars?key=%@&access_token=%@",kGoogleClientID,self.auth.accessToken];

 NSDictionary *params = @{@"summary":@"1233"};

[manager POST:strURL parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
    NSLog(@"JSON: %@", [operation responseString]);
    NSDictionary *dict =(NSDictionary*)responseObject;

    [[NSUserDefaults standardUserDefaults] setObject:[dict objectForKey:@"id"] forKey:KDefaultCalendarID];
    [[NSUserDefaults standardUserDefaults] synchronize];
    [MBProgressHUD hideHUDForView:self.view animated:YES];

} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    [MBProgressHUD hideHUDForView:self.view animated:YES];

    //        [MBProgressHUD hideHUDForView:self.view animated:YES];
    //        UIAlertView *alertView=[[UIAlertView alloc]initWithTitle:@"" message:@"Request failed due to server error. Please try after some time." delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
    //        [alertView show];
}];

问题是使用刷新令牌时,我收到“请求失败:未经授权 (401)” (使用刷新令牌,因为用户不需要每次都登录)

对于用户第一次授权应用后检索到的普通访问令牌(未过期),它可以正常工作。

以下是运行时 url,仅在不使用刷新的访问令牌之前有效。

实际网址:https://www.googleapis.com/calendar/v3/calendars?key=1080844328725-t8jo4s3cpqtg9orcp63lkujh1dvsqugq.apps.googleusercontent.com&access_token=1/x4c8cfLrfYamVgkBqSsi85N34wX7O_IxFutis08BGaN90RDknAdJa_sgfheVM0X

【问题讨论】:

    标签: ios objective-c oauth google-api google-oauth


    【解决方案1】:
    -(void) setNewAccessToken {
    NSString *clientID=kGoogleClientID;
    NSString *clientSecret=kGoogleClientSecret;
    NSString *strRefreshToken;
    
    if([self.auth shouldRefreshAccessToken]) {
        strRefreshToken=self.auth.refreshToken;
    
        NSString *post =[[NSString alloc] initWithFormat:@"client_secret=%@&grant_type=refresh_token&refresh_token=%@&client_id=%@",clientSecret,strRefreshToken,clientID];
        NSLog(@"%@",post);
        NSURL *url=[NSURL URLWithString:@"https://accounts.google.com/o/oauth2/token"];
    
        NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
    
        NSString *postLength = [NSString stringWithFormat:@"%lu", (unsigned long)[postData length]];
    
        NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init] ;
        [request setURL:url];
        [request setHTTPMethod:@"POST"];
        [request setValue:postLength forHTTPHeaderField:@"Content-Length"];
        [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
        [request setHTTPBody:postData];
    
        NSURLConnection *con = [NSURLConnection connectionWithRequest:request delegate:self];
        [con start];
     }
    }
    
    - (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    // The request is complete and data has been received
    // You can parse the stuff in your instance variable now
    NSString *responseJSON;
    
    // This flag indicates whether the response was received after an API call and out of the
    // following cases.
    
    // Convert the received data in NSString format.
    responseJSON = [[NSString alloc] initWithData:(NSData *)_receivedData encoding:NSUTF8StringEncoding];
    
    NSDictionary *dictJsonNotification =
    [NSJSONSerialization JSONObjectWithData: [responseJSON dataUsingEncoding:NSUTF8StringEncoding]
                                    options: NSJSONReadingMutableContainers
                                      error: nil];
    NSLog(@"dictJsonNotification %@",dictJsonNotification);
    
    [[NSUserDefaults standardUserDefaults] setObject:[dictJsonNotification objectForKey:@"access_token"] forKey:KDefaultGmailAccessToken];
    [[NSUserDefaults standardUserDefaults] synchronize];
    
    [self createCalendar1];
    

    }

    然后使用保存的访问令牌进行查询

    【讨论】:

    • 一些解释性文字与答案中的代码一起使用:您无法通过向 API 提供刷新令牌来刷新访问令牌。您需要通过在称为refresh grant 的请求中将刷新令牌提供给令牌端点https://accounts.google.com/o/oauth2/token 来获取新的访问令牌。
    猜你喜欢
    • 2017-07-06
    • 2011-11-16
    • 2017-11-13
    • 1970-01-01
    • 2020-04-10
    • 2018-04-23
    • 2020-03-06
    • 2013-01-01
    • 1970-01-01
    相关资源
    最近更新 更多