上周,我的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:@"&" 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:@"&" 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代码,它们会产生相同的错误。任何类型的见解都会很棒。
答案 0 :(得分:0)
查看您在日志中包含的错误页面,我看到了
The page that you requested is invalid. That's all we know.
我的应用是一个网络服务器应用,但我经常看到在授权期间抛出相同的错误页面。就我而言,我只需返回并重试。
我的工作假设是,它是在Google基础架构中某处抛出的一个瞬态异常,它会产生误导性/无意义的错误消息。
因此,对于您的应用,我可以建议您以某种方式捕获该情况并重试登录。