从这个问题我已经实现了将文件上传到服务器:Upload File to Server
我正在阅读Apple文档以了解NSURLConnection sendSynchronousRequest方法的安全性,并且文档说如果文件需要身份验证,它将使用URL中的凭据。我的问题是,我如何要求身份验证?我假设它在服务器端。
答案 0 :(得分:1)
有大量不同类型的身份验证。有关详细信息,请参阅 URL加载系统编程指南的Authentication Challenges and TLS Chain Validation部分。
但是,在回答您的问题时,是的,您可能希望在Web服务器上使用安全性,然后使用适当的凭据让您的iOS网络请求进行身份验证。如果您只是将您的脚趾浸入经过身份验证的请求的世界中,您应该从HTTP“基本”身份验证开始。 (还有许多其他类型的身份验证,但是通过所有这些身份验证超出了简单的Stack Overflow答案的范围。)
HTTP“基本”身份验证的实现包含两个组件:
在您要进入网站管理的服务器上,将用户ID和密码添加到包含您的Web服务的文件夹中(例如,您与我们共享的该链接中引用的PHP代码)。具体情况会有所不同,具体取决于您拥有的Web服务器。我的ISP提供了“控制面板”,在“安全”部分有一个名为“目录密码”的功能。您的Web服务器可能会有所不同,因此如果不明显,请与您的ISP联系。
在iOS方面,而不是sendSynchronousRequest
(这是一个可怕的解决方案,无论如何;从不做同步网络请求),你想要使用基于委托的NSURLConnection
除了标准didReceiveResponse
,didReceiveData
,connectionDidFinishLoading
和didFailWithError
方法,您还需要编写一个didReceiveAuthenticationChallenge
方法,该方法提供您设置的用户标识和密码在前一步骤中。
在iOS方面,而不是sendSynchronousRequest
,您希望这样做:
[NSURLConnection connectionWithRequest:request delegate:self];
然后实现以下委托方法:
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
int statusCode = [(NSHTTPURLResponse *)response statusCode];
if (statusCode != 200) {
NSLog(@"%s failed status code %d", __FUNCTION__, statusCode);
}
}
self.responseData = [NSMutableData data];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[self.responseData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
// do whatever you want upon success
NSLog(@"%s success; data = %@", __FUNCTION__, [[NSString alloc] initWithData:self.responseData encoding:NSUTF8StringEncoding]);
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
// do whatever you want upon failure
NSLog(@"%s: %@", __FUNCTION__, error);
}
-(void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodHTTPBasic]) {
if ([challenge previousFailureCount] == 0) {
NSURLCredential *credential = [NSURLCredential credentialWithUser:kUsername
password:kPassword
persistence:NSURLCredentialPersistenceForSession];
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
}
else
{
[[challenge sender] cancelAuthenticationChallenge:challenge];
// inform the user that the user name and password
// in the preferences are incorrect
NSLog (@"failed authentication");
// ...error will be handled by connection didFailWithError
}
}
}
显然,这假设您定义了responseData
属性:
@property (nonatomic, strong) NSMutableData *responseData;
现在,我怀疑你正在热衷于所有这些代码的概念,以发送请求并验证该请求。但是,正确的HTTP级别身份验证需要这样的解决方案。像sendSynchronousRequest
这样的便捷方法(你应该避免,无论如何)和sendAsynchronousRequest
(这是更好的,但仍然不能处理这样的身份验证挑战)只是不能胜任这项任务。如果您不想编写所有这些代码,那么您可以考虑使用类似AFNetworking的库来执行所有这类代码(以及更多),并让您摆脱杂草处理这样的网络请求。