【发布时间】:2016-05-04 03:38:22
【问题描述】:
我正在尝试访问网页以检索 JSON data。
当我通过浏览器访问该页面时,它会显示一个小框,说需要身份验证该站点正在请求用户名和密码:" API""
我试图让这些数据传递给NSdictionary 对象。
我发现我对 HTTP 请求的响应是“401 - 未经授权:由于凭据无效,访问被拒绝。您无权使用您提供的凭据查看此目录或页面”
仅供参考,我在请求的授权标头中传递了用户名和密码。
但是我在浏览器中找到了它会要求的内容
WWW-Authenticate: Basic realm="API"在获取或显示数据之前
我找了一个解决方案,我红了NSURLCredential 所以我实现了NSURLsession delegate 来触发它的功能(
- (void)URLSession:(NSURLSession *)session
didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition,
NSURLCredential *credential))completionHandler
) 但它从未被调用,我不知道为什么
我该怎么办?
这是我的代码:
+(void)getUsername:(NSString*)username andPassword:(NSString*)password completionBlock:(void(^)(NSDictionary* response))completion
{
NSString *authStr = [NSString stringWithFormat:@"%@:%@", username, password];
NSData *authData = [authStr dataUsingEncoding:NSUTF8StringEncoding];
NSString *base64String = [authData base64EncodedStringWithOptions:0];
NSString *authValue = [NSString stringWithFormat:@"Basic %@", base64String];
__block NSDictionary *currentUserdictionarytest = nil;
NSDictionary *headers = @{ @"authorization": authValue,
@"accept": @"application/json",
@"accept": @"text/html",
@"cache-control": @"no-cache",
@"postman-token": @"0a47efb3-c559-c0f9-8276-87cbdbe76c9d" };
NSString *url = @"http://demo.redmine.org/";
stringByAppendingString:@"users/current.json"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:10.0];
[request setHTTPMethod:@"GET"];
[request setAllHTTPHeaderFields:headers];
NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration: defaultConfigObject delegate: self delegateQueue:nil]; //[NSOperationQueue mainQueue]]; //[NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
NSLog(@"%@", error);
} else {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
NSLog(@"%@", httpResponse);
NSError *JSONError = nil;
currentUserdictionarytest = [NSJSONSerialization JSONObjectWithData:data
options:0
error:&JSONError];
NSLog(@"Printing current user data: %@", data);
NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"Printing current user data string: %@", str);
if (JSONError)
{
NSLog(@"Serialization error: %@", JSONError.localizedDescription);
}
else
{
NSLog(@"Response: %@", currentUserdictionarytest);
}
}
}];
[dataTask resume];
}
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler
{
NSLog(@"did receive challenge method called with task");
NSString* username = @"username";
NSString* password = @"password";
if ([challenge previousFailureCount] == 0) {
NSURLCredential *newCredential;
newCredential = [NSURLCredential credentialWithUser:username
password:password
persistence:NSURLCredentialPersistenceNone];
[[challenge sender] useCredential:newCredential
forAuthenticationChallenge:challenge];
} else {
[[challenge sender] cancelAuthenticationChallenge:challenge];
}
}
【问题讨论】:
-
您需要传递您的实际用户名和密码,该用户名和密码被授权访问此页面,除非您的代码没有问题。
-
我知道当管理员用户请求此数据时我的代码运行良好,但是当普通用户请求数据时它给出了“401”错误。我已阅读有关使用 NSURLProtectionSpace 的信息,但我不知道在哪里传递这个对象或在哪里使用它。
-
你可以查看这个帖子Can I use NSURLCredentialStorage for HTTP Basic Authentication?。这可能会有所帮助。
-
我做了正确的事情,我为 initWithHost:@"example.com" port:80 protocol:@"http" realm:@"API" authenticationMethod:NSURLAuthenticationMethodHTTPBasic];但它仍然给我同样的错误!
标签: ios objective-c basic-authentication nsurlsession