0

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

        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 代码,它们产生了同样的错误。任何类型的洞察力都会很棒。

4

1 回答 1

0

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

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

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

我的工作假设是,这是在 Google 基础架构中某个地方抛出的临时异常,它体现在一个误导性/无意义的错误消息中。

因此,对于您的应用程序,我只能建议您以某种方式捕获这种情况并重试登录。

于 2013-10-28T04:33:10.187 回答