我正在尝试对需要相互身份验证的服务器进行API调用。 使用NodeJS和请求库,我可以使用以下代码
来访问APIvar keyFile = '/Users/username/Documents/Certificates/example-key.pem';
var certificateFile = '/Users/username/Documents/Certificates/cert.pem';
var options = {
uri: 'https://myserver.com/apiOne',
key: fs.readFileSync(keyFile),
cert: fs.readFileSync(certificateFile),
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Basic ' + new Buffer(userId + ':' + password).toString('base64')
},
body: data //JSON body
};
request.postAsync(options)
.spread(function (response, body) {
res.status(200).json(JSON.parse(body));
})
.catch(function (err) {
res.status(400).send(err);
})
如何从iOS应用中获得相同的API? 我使用以下代码,但服务器没有响应
func URLSession(session: NSURLSession, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential!) -> Void) {
if challenge.protectionSpace.authenticationMethod == "NSURLAuthenticationMethodServerTrust" {
let credential = NSURLCredential(forTrust: challenge.protectionSpace.serverTrust)
NodeJS代码中的密钥和证书是什么意思?我如何在iOS中传递它们?
答案 0 :(得分:1)
首先,您需要将密钥和证书转换为p12文件。 为此,请运行以下命令
openssl pkcs12 -export -out new.p12 -inkey example-key.pem -in cert.pem
它还会提示您输入密码。在以下代码中使用此创建的p12和密码的路径
#pragma mark - Get Identity
- (SecIdentityRef)getIdentity {
SecIdentityRef identity = nil;
CFStringRef password = (__bridge CFStringRef)certPassword; //the password that you entered while creating the p12 file
const void *keys[] = { kSecImportExportPassphrase };
const void *values[] = { password };
CFDictionaryRef options = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL);
NSData *certData = [NSData dataWithContentsOfFile:certFilePath]; //the path to the p12 file. You can get this from bundle
CFArrayRef items = CFArrayCreate(nil, 0, 0, nil);
OSStatus status = SecPKCS12Import((__bridge CFDataRef)(certData), options, &items);
CFRelease(options);
CFRelease(password);
if (status == errSecSuccess) {
NSLog(@"Success opening p12 certificate. Items: %ld", CFArrayGetCount(items));
CFDictionaryRef identityDict = CFArrayGetValueAtIndex(items, 0);
identity = (SecIdentityRef)CFDictionaryGetValue(identityDict, kSecImportItemIdentity);
} else {
NSLog(@"Error opening Certificate.");
}
return identity;
}
#pragma mark - Get Certificates
- (CFArrayRef)getCertificates:(SecIdentityRef) identity {
SecCertificateRef certificate = nil;
SecIdentityCopyCertificate(identity, &certificate);
SecCertificateRef certs[1] = { certificate };
CFArrayRef array = CFArrayCreate(NULL, (const void **) certs, 1, NULL);
return array;
}
- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler {
NSString *authMethod = challenge.protectionSpace.authenticationMethod;
NSLog(@"auth method %@", authMethod);
if ([authMethod isEqualToString:@"NSURLAuthenticationMethodServerTrust"] || [authMethod isEqualToString:@"NSURLAuthenticationMethodClientCertificate"]) {
SecIdentityRef identity = [self getIdentity]; // Go get a SecIdentityRef
CFArrayRef certs = [self getCertificates:identity]; // Get an array of certificates
NSArray *myArray = (__bridge NSArray *)certs;
NSURLCredential *newCredential = [NSURLCredential credentialWithIdentity:identity certificates:myArray persistence:NSURLCredentialPersistencePermanent];
[challenge.sender useCredential:newCredential forAuthenticationChallenge:challenge];
completionHandler(NSURLSessionAuthChallengeUseCredential, newCredential);
}
}