Google OAuth突然无法使用AFNetworkingErrorDomain

时间:2013-10-27 17:16:51

标签: ios oauth google-oauth

上周,我的iOS应用中的Google OAuth部分完全停止了工作。用户将其详细信息输入应用程序中的自定义登录字段,然后通过Google授权,创建令牌,并告诉他们他们的登录成功(在应用程序内)。相反,他们看到登录失败的消息。我似乎无法弄清楚为什么(Google改变了什么?)但是当用户尝试登录时我得到的错误代码如下:

        2013-10-27 12:49:56.137 XXXX [1210:1a003] URL is https://accounts.google.com/o/oauth2/approval?as=1e543c0fe20b1da5&hl=en_GB&pageId=none&xsrfsign=APsBz4gAAAAAUm1LHD2mXAhs8QexAFwlf9KVIt5UdNj_
    2013-10-27 12:49:57.776 XXXX[1210:1a003] 333
    2013-10-27 12:49:57.776 XXXX[1210:1a003] Failed: -1011
    2013-10-27 12:49:57.777 XXXX[1210:1a003] Description: Error
Domain=AFNetworkingErrorDomain Code=-1011 "Expected status code in (200-299), got 400" 
UserInfo=0x96b5700 {NSLocalizedRecoverySuggestion=<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 
4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><title>Google 
Accounts</title><meta http-equiv="content-type" content="text/html; charset=utf-8"><meta 
name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-
scale=1, user-scalable=0" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><link 
rel='stylesheet' type='text/css' href='https://ssl.gstatic.com/accounts/o/1893590695-error_page_css_ltr.css'>
    <script type="text/javascript" src="https://ssl.gstatic.com/accounts/o/708588620-common_lib.js"></script>
    <style>@media screen and (max-width:500px) {#robot {background: none; min-height: 0; min-width: 0; padding: 0;}#stack_trace {display: none;}}
    #oauth2_request_info_header {background-image: url("https://ssl.gstatic.com/accounts/o/blank.gif");}</style></head><body ><div id="robot"></div><a href="//www.google.com/" id="googlelogo"><img src="//www.google.com/images/logo_sm.gif" alt="Google"></a><p class="large"><b>400.</b> <ins>That's an error.</ins></p><p class="large">The page that you requested is invalid.  <ins>That's all we know.</ins></p></body></html>, AFNetworkingOperationFailingURLRequestErrorKey=<NSMutableURLRequest https://accounts.google.com/o/oauth2/approval?as=1e543c0fe20b1da5&hl=en_GB&pageId=none&xsrfsign=APsBz4gAAAAAUm1LHD2mXAhs8QexAFwlf9KVIt5UdNj_>, NSErrorFailingURLKey=https://accounts.google.com/o/oauth2/approval?as=1e543c0fe20b1da5&hl=en_GB&pageId=none&xsrfsign=APsBz4gAAAAAUm1LHD2mXAhs8QexAFwlf9KVIt5UdNj_, NSLocalizedDescription=Expected status code in (200-299), got 400, AFNetworkingOperationFailingURLResponseErrorKey=<NSHTTPURLResponse: 0x96aae40>}

以下是似乎导致错误的代码部分:

-(void)doSignInStep2:(NSString*)response
{
   // NSLog(@"RESPONSE: %@", response);

    NSString *form = [response substringFromIndex:[response rangeOfString:@"form "].location];
    form = [form substringToIndex:[form rangeOfString:@"</form>"].location];

    NSString *formAction = [form substringFromIndex:[form rangeOfString:@"action="].location + 8];
    formAction = [formAction substringToIndex:[formAction rangeOfString:@"\""].location];

    if ([formAction rangeOfString:@"'"].location != NSNotFound)
    {
        formAction = [formAction substringToIndex:[formAction rangeOfString:@"'"].location];
    }


    formAction = [formAction stringByReplacingOccurrencesOfString:@"&amp;" withString:@"&"];

    //get all input elements in the form
    NSMutableArray *elements = [[NSMutableArray alloc] init];

    NSRange rng = [form rangeOfString:@"<input "];

    while (rng.location != NSNotFound)
    {
        NSString *inputItem = [form substringFromIndex:rng.location];
        NSInteger *inputItemLength = [inputItem rangeOfString:@">"].location + 1;
        inputItem = [inputItem substringToIndex:inputItemLength];

        NSString *elementName = nil;
        NSString *elementValue = nil;

        NSRange iiRange = [inputItem rangeOfString:@"name=\""];

        if (iiRange.location != NSNotFound) {
            elementName = [inputItem substringFromIndex:iiRange.location + 6];
            elementName = [elementName substringToIndex:[elementName rangeOfString:@"\""].location];
        }

        iiRange = [inputItem rangeOfString:@"value=\""];

        if (iiRange.location != NSNotFound) {
            elementValue = [inputItem substringFromIndex:iiRange.location + 7];
            elementValue = [elementValue substringToIndex:[elementValue rangeOfString:@"\""].location];

            elementValue = [elementValue stringByReplacingOccurrencesOfString:@"&amp;" withString:@"&"];
        }

        if (elementName && elementValue) {
            NSString *encodedstring = (__bridge NSString *)CFURLCreateStringByAddingPercentEscapes(NULL,
                                                                                                   (__bridge CFStringRef)elementValue,
                                                                                                   NULL,
                                                                                                   (CFStringRef)@"!*'();:@&=+$,/?%#[]",
                                                                                                   kCFStringEncodingUTF8);

            if (![elementName isEqualToString:@"submit_access"])
                [elements addObject:[NSMutableArray arrayWithObjects:elementName, encodedstring, nil]];
        }

        form = [form substringFromIndex:rng.location];

        form = [form substringFromIndex:inputItemLength];

        rng = [form rangeOfString:@"<input "];
    }

    [elements addObject:[NSMutableArray arrayWithObjects:@"submit_access", @"true", nil]];


    NSString *params = @"";

    for (int i = 0; i < [elements count]; i++)
    {
        NSMutableArray *element = [elements objectAtIndex:i];

        if ([params length] > 0)
            params = [params stringByAppendingString:@"&"];

        params = [params stringByAppendingString:[element objectAtIndex:0]];
        params = [params stringByAppendingString:@"="];
        params = [params stringByAppendingString:[element objectAtIndex:1]];
    }

    //NSLog(@"Params: %@", params);

    NSURL *url = [NSURL URLWithString:formAction];
    NSLog(@"URL is %@", url);
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    [request setCachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData];
    [request setHTTPMethod:@"POST"];
    [request setHTTPBody:[params dataUsingEncoding:NSUTF8StringEncoding]];
    //[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
    //[request setValue:[params length] forHTTPHeaderField:@"Content-Length"];

    AFHTTPRequestOperation *op3 = [[AFHTTPRequestOperation alloc] initWithRequest:request];

    [op3 setCompletionBlockWithSuccess:  ^(AFHTTPRequestOperation *operation, NSError *error) {
        NSString *response = [[NSString alloc] initWithData:operation.responseData encoding:NSUTF8StringEncoding];

        [self doSignInStep3:response];


    }failure: ^(AFHTTPRequestOperation *operation, NSError *error)
     {
         NSLog(@"333");
         NSLog(@"Failed: %d", error.code);
         NSLog(@"Description: %@", error.description);

         //NSLog(@"Response: %@", [[NSString alloc] initWithData:operation.responseData encoding:NSUTF8StringEncoding]);


         [self.delegate finishedSignIn:[NSNumber numberWithBool:NO] response:nil];
     }];

    [op3 start];

}

和...

-(void)doSignInStep3:(NSString*)response
{
    //NSLog(@"Response: %@", response);


    //<input id="code" type="text" readonly="readonly" value="4/Zvd-PjWHw53BqdSzExYus1MsT9dx.snLL4gUE1cocOl05ti8ZT3bZAne4dgI"
    if ([response rangeOfString:@"<input id=\""].location == NSNotFound)
    {

        [self.delegate finishedSignIn:[NSNumber numberWithBool:NO] response:nil];
    }
    else
    {
        NSString *code = [response substringFromIndex:[response rangeOfString:@"<input id=\""].location];

        code = [code substringFromIndex:[code rangeOfString:@"value=\""].location + 7];

        code = [code substringToIndex:[code rangeOfString:@"\""].location];

        NSURL *url = [NSURL URLWithString:@"https://accounts.google.com/o/oauth2/token"];

        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
        [request setCachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData];
        [request setHTTPMethod:@"POST"];

        //NSLog(@"Code: %@", code);

        NSString *params = [NSString stringWithFormat:@"code=%@", code];
        params = [params stringByAppendingString:[NSString stringWithFormat:@"&client_id=%@", client_id]];
        params = [params stringByAppendingString:[NSString stringWithFormat:@"&client_secret=%@", client_secret]];
        params = [params stringByAppendingString:@"&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob"];
        params = [params stringByAppendingString:@"&grant_type=authorization_code"];
        //params = [params stringByAppendingString:@"&approval_prompt=force"];

        [request setHTTPBody:[params dataUsingEncoding:NSUTF8StringEncoding]];
        [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];

        AFHTTPRequestOperation *op4 = [[AFHTTPRequestOperation alloc] initWithRequest:request];

        [op4 setCompletionBlockWithSuccess:  ^(AFHTTPRequestOperation *operation, NSError *error) {
            NSString *response = [[NSString alloc] initWithData:operation.responseData encoding:NSUTF8StringEncoding];

            //NSLog(@"Response: %@", response);

            [self processResponse:response];

            [self.delegate finishedSignIn:[NSNumber numberWithBool:YES] response:response];

        }failure: ^(AFHTTPRequestOperation *operation, NSError *error)
         {
             NSLog(@"444");
             NSLog(@"Failed: %d", error.code);
             NSLog(@"Description: %@", error.description);

             //NSLog(@"Response: %@", [[NSString alloc] initWithData:operation.responseData encoding:NSUTF8StringEncoding]);

             [self.delegate finishedSignIn:[NSNumber numberWithBool:NO] response:nil];
         }];

        [op4 start];


    }
}

我在这里完全失败,因为之前一切都很好,我的结局没有任何影响。什么会导致这种情况完全停止工作?我已经尝试过新的client_id和client_secret代码,它们会产生相同的错误。任何类型的见解都会很棒。

1 个答案:

答案 0 :(得分:0)

查看您在日志中包含的错误页面,我看到了

The page that you requested is invalid. That's all we know.

我的应用是一个网络服务器应用,但我经常看到在授权期间抛出相同的错误页面。就我而言,我只需返回并重试。

我的工作假设是,它是在Google基础架构中某处抛出的一个瞬态异常,它会产生误导性/无意义的错误消息。

因此,对于您的应用,我可以建议您以某种方式捕获该情况并重试登录。