我正在尝试通过AFHTTPRequestOperation
将照片上传到我的网络服务器。这是我的AFHTTPSessionManager
。通过此manager
的所有http请求都可以完美运行。
- (AFHTTPSessionManager *)manager
{
if (_manager == nil) {
_manager = [[AFHTTPSessionManager alloc] initWithBaseURL:[NSURL URLWithString:@"https://my.domain.com/api/v2"]];
[_manager.requestSerializer setAuthorizationHeaderFieldWithUsername:@"username" password:@"password"];
AFSecurityPolicy *policy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone];
policy.allowInvalidCertificates = YES;
_manager.securityPolicy = policy;
}
return _manager;
}
但是当我尝试使用进度处理上传照片时:
- (void)photoSend:(UIImage *)photo
toUsers:(NSArray *)users
completion:(CompletionHandler)completion
progress:(ProgressionHandler)progress
{
NSDictionary *params = @{
@"token":self.token,
@"to_usernames":[users componentsJoinedByString:@","],
};
NSString *urlString = [[NSURL URLWithString:@"photo/send" relativeToURL:self.manager.baseURL] absoluteString];
NSMutableURLRequest *request = [self.manager.requestSerializer multipartFormRequestWithMethod:@"POST" URLString:urlString parameters:params constructingBodyWithBlock:^(id <AFMultipartFormData> formData)
{
[formData appendPartWithFileData:UIImageJPEGRepresentation(photo,0.8)
name:@"photo"
fileName:@"image.jpg"
mimeType:@"image/jpg"];
} error:nil];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
operation.responseSerializer = [AFJSONResponseSerializer serializer];
// Following 2 lines does not make sense. Http headers contains auth data without this code
//NSURLCredential *credential = [NSURLCredential credentialWithUser:@"login" password:@"password" persistence:NSURLCredentialPersistenceNone];
//[operation setCredential:credential];
[operation setUploadProgressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) {
progress(totalBytesWritten*1.0/totalBytesExpectedToWrite);
}];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
completion(operation.response, responseObject, operation.error);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
completion(operation.response, nil, error);
}];
[self.manager.operationQueue addOperation:operation];
}
我收到以下错误:
错误域= NSURLErrorDomain代码= -1012&#34;操作不能 完成。 (NSURLErrorDomain错误-1012。)&#34;的UserInfo = 0x994ff20 {NSErrorFailingURLKey = https://my.domain.com/v2/photo/send, NSErrorFailingURLStringKey = https://my.domain.com/v2/photo/send}
答案 0 :(得分:8)
以下是解决方案:
AFSecurityPolicy *policy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone];
policy.allowInvalidCertificates = YES;
operation.securityPolicy = policy;
因此,HTTP基本身份验证数据由管理员提供给操作,但SSL策略 - 不是。
答案 1 :(得分:1)
在AFNetworking
中,您可以使用AFSSLPinningMode
对安全策略进行更改,因此如果您的服务器未安装SSL,请使用以下代码
let operation = AFHTTPRequestOperation(request: YourMutableRequestObject)
let policy = AFSecurityPolicy(pinningMode: AFSSLPinningMode.None)
policy.validatesDomainName = false
policy.allowInvalidCertificates = true
operation.securityPolicy = policy
如果您的服务器使用的是证书,则可以使用以下代码
let operation = AFHTTPRequestOperation(request: YourMutableRequestObject)
let policy = AFSecurityPolicy(pinningMode: AFSSLPinningMode.Certificate)
policy.validatesDomainName = false
policy.allowInvalidCertificates = true
operation.securityPolicy = policy
在使用上述代码之前,请确保您已在应用程序包中添加了cer
证书,如果不是,您将无法拨打电话,您可以从Web开发人员处获取cer文件或任何向你提供cer的权威。
如果您从Web开发人员那里收到crt文件,则需要使用以下代码使用OpenSSL
将其转换为cer
openssl x509 -in apache.crt -out yourCertFileName.cer -outform der
这应该足以进行调用
<强>更新强>
根据Apple在iOS 9中的新ATS模式,您必须在info.plist
文件中提供一些权限。
如果您想要进行不安全的调用,请在下面提供您需要在info.plist
内集成的XML(请注意,您不会在此处获取任何自动填充程序,您必须将您的plist视为来源和复制+粘贴下面的内容)
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>yourserver.com</key>
<dict>
<!--Include to allow subdomains-->
<key>NSIncludesSubdomains</key>
<true/>
<!--Include to allow HTTP requests-->
<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
<true/>
<!--Include to specify minimum TLS version-->
<key>NSTemporaryExceptionMinimumTLSVersion</key>
<string>TLSv1.1</string>
</dict>
</dict>
</dict>
Apple还提供了一种禁用ATS的方法,下面给出的是同样的XML,但不推荐
<key>NSAppTransportSecurity</key>
<dict>
<!--Include to allow all connections -->
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
在我的情况下,因为我的服务器使用自签名证书,我只是将AFSSLPinningMode
更改为证书,它按预期工作。
希望这有助于某人