我设置了一个cocoa类,我想用它来连接到我正在构建的RESTful web服务。我已经决定在我的PHP后端使用HTTP Basic Authentication,就像这样…
<?php
if (!isset($_SERVER['PHP_AUTH_USER'])) {
header('WWW-Authenticate: Basic realm="My Realm"');
header('HTTP/1.0 401 Unauthorized');
//Stuff that users will see if they click 'Cancel'
exit;
}
else {
//Validation Code
echo "You entered info.";
}
?>在这一点上,我使用的是同步NSURLConnection,据我所知,苹果文档中指出,它对身份验证的支持较少。
但这到底有没有可能呢?我可以很容易地通过NSURLProtectionSpaces或NSURLCredentials或任何身份验证类进行cookie身份验证。另外,有没有什么资源可以让我了解更多关于Cocoa身份验证类的信息?
谢谢。
更新: mikeabdullahuk您提供的代码(第二个示例)与我编写的代码几乎相同。我做了进一步的调查,发现NSURLConnection返回了一个错误的…
Error Domain=NSURLErrorDomain Code=-1012 UserInfo=0x1a5170 "Operation could not be completed. (NSURLErrorDomain error -1012.)"代码对应于NSURLErrorUserCancelledAuthentication。因此,很明显,我的代码没有访问NSURLCredentialStorage,而是取消了身份验证。这可能与PHP HTTP身份验证函数有关吗?在这一点上我很困惑。
发布于 2009-02-02 00:01:26
同步NSURLConnection绝对可以与NSURLCredentialStorage一起工作。事情通常是这样的:
NSURLConnection向服务器请求页面responseNSURLConnection服务器回复401 NSURLConnection还将咨询NSURLCredentialStorage以填补空白NSURLConnection将发送D19委托方法,要求提供完整凭据d22现在终于具有完整的凭据,它将重试包括授权数据在内的原始请求。通过使用同步连接方法,您只会在步骤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];发布于 2009-02-03 23:34:17
在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的情况,因为服务器实际上并没有发送HTTP401(例如,它发送的是常规页面)。
发布于 2009-02-02 17:54:19
我要指出的是,mikeabdullahuk的答案是好的,但如果你使用NSURLCredentialPersistencePermanent而不是每个会话,它会将凭证存储在用户的密钥链中,所以下次你可以检查NSURLCredentialStorage中保护空间的默认凭证的非nil值,如果你得到一个非nil值,你只需传递凭证即可。我现在正在为我正在编写的delicious.com客户端使用这个方法,它在我的测试中工作得非常好。
https://stackoverflow.com/questions/501231
复制相似问题