我有一个cocoa类设置,我想用它连接到我正在构建的RESTful Web服务.我决定在我的PHP后端使用HTTP基本身份验证,就像这样......
此时我正在使用同步NSURLConnection,我了解Apple文档状态对身份验证的支持较少.
但它甚至可能吗?我可以非常轻松地进行cookie身份验证,无需NSURLProtectionSpaces或NSURLCredentials或任何身份验证类.此外,是否有任何资源,我可以阅读更多关于Cocoa身份验证类?
谢谢.
更新:mikeabdullahuk您提供的代码(第二个示例)几乎与我所写的相同.我做了一些调查,发现NSURLConnection正在返回错误......
Error Domain=NSURLErrorDomain Code=-1012 UserInfo=0x1a5170 "Operation could not be completed. (NSURLErrorDomain error -1012.)"
该代码对应于NSURLErrorUserCancelledAuthentication.显然我的代码没有访问NSURLCredentialStorage,而是取消了身份验证.这可能与PHP HTTP身份验证功能有关吗?我现在很困惑.
同步NSURLConnection
绝对可以使用NSURLCredentialStorage
.事情通常是如何运作的:
NSURLConnection
从服务器请求页面
服务器回复401响应
NSURLConnection
看看它可以从URL中收集哪些凭据
如果URL并没有提供完整的凭据(用户名和密码),NSURLConnection
亦会咨询NSURLCredentialStorage
,填补了国内空白
如果仍未确定完整凭据,NSURLConnection
则将发送-connection:didReceiveAuthenticationChallenge:
委托方法请求凭据
如果NSURLConnection
现在最终具有完整凭证,则它将重试原始请求,包括授权数据.
通过使用同步连接方法,您只能在步骤5中失去提供自定义身份验证的能力.因此,您可以在URL中预先提供身份验证凭据,也可以NSURLCredentialStorage
在发送请求之前将其置于其中.例如
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://user:pass@example.com"]]; [NSURLConnection sendSynchronousRequest:request returningResponse:NULL error:NULL];
要么:
NSURLCredential *credential = [NSURLCredential credentialWithUser:@"user" password:@"pass" persistence:NSURLCredentialPersistenceForSession]; NSURLProtectionSpace *protectionSpace = [[NSURLProtectionSpace alloc] initWithHost:@"example.com" port:0 protocol:@"http" realm:nil authenticationMethod:nil]; [[NSURLCredentialStorage sharedCredentialStorage] setDefaultCredential:credential forProtectionSpace:protectionSpace]; [protectionSpace release]; NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://example.com"]]; [NSURLConnection sendSynchronousRequest:request returningResponse:NULL error:NULL];
在401或其他身份验证挑战不可接受/不可能的情况下,我有时会使用虚拟CFHTTPMessage生成验证行,然后将其复制回NSURLRequest:
// assume NSString *username and *password exist and NSURLRequest *urlRequest // exists and is fully configured except for HTTP Basic Authentication.. CFHTTPMessageRef dummyRequest = CFHTTPMessageCreateRequest( kCFAllocatorDefault, CFSTR("GET"), (CFURLRef)[urlRequest URL], kCFHTTPVersion1_1); CFHTTPMessageAddAuthentication( dummyRequest, nil, (CFStringRef)username, (CFStringRef)password, kCFHTTPAuthenticationSchemeBasic, FALSE); authorizationString = (NSString *)CFHTTPMessageCopyHeaderFieldValue( dummyRequest, CFSTR("Authorization")); CFRelease(dummyRequest); [urlRequest setValue:authorizationString forHTTPHeaderField:@"Authorization"];
这似乎完全是一种奇怪的方式,但它可以容忍用户名/密码不是URL清理的情况,以及NSURLRequest拒绝咨询NSURLCredentialStorage的情况,因为服务器实际上并没有发送HTTP 401(例如它发送改为常规页面).