NSURLConnection授权头不起作用

22

我正试图通过NSURLConnection在HTTP头中发送OAuth访问令牌,但似乎没有发送该标头,因为API一直给我一个错误,说���必须提供授权令牌”。

这是我正在使用的代码:

NSURL *aUrl = [NSURL URLWithString: @"http://generericfakeapi.com/user/profile"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:aUrl
                                                       cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                   timeoutInterval:30.0];

[request addValue:[NSString stringWithFormat:@"OAuth %@", token] forHTTPHeaderField:@"Authorization"];

[request setHTTPMethod:@"GET"];

NSError *error = nil;
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error: &error];

NSDictionary *JSONDictionary = [NSJSONSerialization JSONObjectWithData:returnData options:kNilOptions error:&error];
NSLog(@"Response : %@", JSONDictionary);

这是API的cURL命令示例:

curl 'http://generericfakeapi.com/user/profile' -H 'Authorization: OAuth YourAuthToken'

这不就是我通过NSURLConnection本质上正在做的吗?

任何帮助都将不胜感激。

4个回答

57

更改这一行:

NSURL *aUrl = [NSURL URLWithString: @"http://generericfakeapi.com/user/profile"];

收件人:

NSURL *aUrl = [NSURL URLWithString: @"http://generericfakeapi.com/user/profile/"];

显然,如果URL末尾没有斜杠,iOS会删除Authorization标头。这个问题让我彻夜难眠两天。


1
+1 简单的解决方案。我也遇到了同样的问题,幸运的是没有失眠。然而,我尝试搜索更多信息,不幸的是没有人有清晰的解释。知道为什么(以及到什么时候)将非常有帮助。 - Subhash Dike
1
非常感谢,我遇到了同样的问题。似乎iOS将以斜杠结尾的URL和不以斜杠结尾的URL视为两种不同的情况。 - Chauyan
1
你救了我的一天,我已经花费了4个关键小时在这上面,然后发现了你的答案。 - Iqbal Khan
1
谢谢,甚至都不确定浪费了多少个小时尝试不同的方法! - kos
1
我花了4个小时来调试问题。 - Saqib Omer
同样的,花了几个小时来调试……最后只为了一个斜杠 -.-' - Elvereth

2

@isair的回答真是救命稻草。

如果您感兴趣,以下是根本原因的补充说明:

NSURLRequest定义了一组保留的HTTP头文件。令人惊讶的是,Authorization也是其中之一。

URL加载系统为您处理HTTP协议的各个方面(HTTP 1.1持久连接、代理、身份验证等)。作为此支持的一部分,URL加载系统负责某些HTTP标头:

  • Content-Length

  • Authorization

  • Connection

  • Host

  • Proxy-Authenticate

  • Proxy-Authorization

  • WWW-Authenticate

如果您为这些保留标头之一设置值,则系统可能会忽略您设置的值,或者用自己的值覆盖它,或者根本不发送它。此外,确切的行为可能随时间而改变。为避免出现这种混淆问题,请勿直接设置这些标头。

在@isair的情况下,没有尾随斜杠的URL很可能会触发这种“过滤”行为。这可能是实现中的不一致性,但我们无法访问源代码来验证。

在我的情况下,我正在编写一个使用Authorization头与后端Django服务器进行身份验证的React webapp。桌面Chrome上的应用程序表现完美,但在iPhone上(Safari和Chrome)始终无法访问login-required API,因为缺少Authorization头文件。

理想的解决方案是完全避免使用Authorization。但如果您要与特定要求它的后端框架通信(例如Django Rest Framework的令牌身份验证),@isair的答案可以是一个不错的解决方法。


1

对我来说,它看起来很好。你确定给出了有效的令牌吗? 像这样尝试捕获错误

if (error) {
    NSLog(@"error : %@", error.description);
}

My code work well :

NSURL *jsonURL = [NSURL URLWithString:[NSString stringWithFormat:@"http://....ID=%i", cellID]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:jsonURL cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:120.0];
[request setValue:@"Basic ...." forHTTPHeaderField:@"Authorization"];
NSURLResponse *response;
NSError * error  = nil;
NSData *POSTReply = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];

希望它有所帮助。

0

我曾经遇到过同样的问题。在我的情况下,我将“http”更改为“https”,然后一切正常了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接