我正在使用AFNetworking的AFHTTPClient从我的IOS应用程序拨打我的服务器,该服务器正在使用带有TastyPie的Django。当我在服务器端关闭身份验证时,它工作得很好;但是,当我需要身份验证并在我的代码中插入正确的用户名和密码时,我收到以下401身份验证错误:
\2012-09-16 00:24:37.877 RESTtest[76909:f803]
Complex AF: Error Domain=AFNetworkingErrorDomain Code=-1011
"Expected status code in (200-299), got 401"
UserInfo=0x686ba00 {AFNetworkingOperationFailingURLResponseErrorKey=<NSHTTPURLResponse: 0x686f130>,
NSErrorFailingURLKey=http://127.0.0.1:8000/api/v1/shoppinglist,
NSLocalizedDescription=Expected status code in (200-299), got 401,
AFNetworkingOperationFailingURLRequestErrorKey=<NSMutableURLRequest http://127.0.0.1:8000/api/v1/shoppinglist>}
这是我的代码:
AFAPIClient.h #import“AFHTTPClient.h”
@interface AFAPIClient : AFHTTPClient
-(void)setUsername:(NSString *)username andPassword:(NSString *)password;
+ (AFAPIClient *)sharedClient;
@end
AFAPIClient.m:
#import "AFAPIClient.h"
#import "AFJSONRequestOperation.h"
static NSString * const baseURL = @"http://@127.0.0.1:8000/api/v1";
@implementation AFAPIClient
+ (AFAPIClient *)sharedClient {
static AFAPIClient *_sharedClient = nil;
static dispatch_once_t pred;
dispatch_once(&pred, ^{
_sharedClient = [[AFAPIClient alloc] initWithBaseURL:[NSURL URLWithString:baseURL]];
//[_sharedClient setAuthorizationHeaderWithUsername:@"myusername" password:@"mypassword"]; I tried putting the authorization command here
});
return _sharedClient;
};
#pragma mark - Methods
-(void)setUsername:(NSString *)username andPassword:(NSString *)password;
{
[self clearAuthorizationHeader];
[self setAuthorizationHeaderWithUsername:username password:password];
}
- (id)initWithBaseURL:(NSURL *)url
{
self = [super initWithBaseURL:url];
if (!self) {
return nil;
}
[self registerHTTPOperationClass:[AFJSONRequestOperation class]];
[self setParameterEncoding:AFJSONParameterEncoding];
//[self setAuthorizationHeaderWithUsername:@"myusername" password:@"mypassword"]; I also tried putting the authorization command here
// Accept HTTP Header; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1
[self setDefaultHeader:@"Accept" value:@"application/json"];
return self;
}
@end
TQViewController.h:
[...]
- (IBAction)sendAFClientRequest:(id)sender {
//[[AFAPIClient sharedClient] setUsername:@"myusername" andPassword:@"mypassword"];
[[AFAPIClient sharedClient] getPath:@"shoppinglist" parameters:nil success:^(AFHTTPRequestOperation *operation, id response) {
NSLog(@"Complex AF: %@", [response valueForKeyPath:@"objects"]);
} failure:^(AFHTTPRequestOperation *operation, id response) {
NSLog(@"Complex AF: %@", response);
}
];
}
[...]
我知道这不是我的服务器或我的用户名/密码的问题,因为我可以通过在URL中插入用户名/密码来进行身份验证:
@"http://myusername:mypassword@127.0.0.1:8000/api/v1/shoppinglist"
对此的任何帮助都会很棒。如果能够使用AFHTTPClient而不将身份验证信息直接插入到静态基本URL中,这将是非常好的,这似乎完全不合适。提前谢谢!
答案 0 :(得分:4)
基于此:https://github.com/AFNetworking/AFNetworking/issues/426
我覆盖了AFHTTPClient中的- (void)getPath:(NSString *)path parameters...
方法
子类看起来像这样:
- (void)getPath:(NSString *)path parameters:(NSDictionary *)parameters
success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure
{
NSURLRequest *request = [self requestWithMethod:@"GET" path:path parameters:parameters];
AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithRequest:request success:success failure:failure];
[operation setAuthenticationChallengeBlock:^(NSURLConnection *connection, NSURLAuthenticationChallenge *challenge) {
NSURLCredential *newCredential = [NSURLCredential credentialWithUser:self.username password:self.password persistence:NSURLCredentialPersistenceForSession];
[challenge.sender useCredential:newCredential forAuthenticationChallenge:challenge];
}];
[self enqueueHTTPRequestOperation:operation];
}
它只将身份验证质询块添加到AFHTTPRequestOpertaion,其余部分与原始实现https://github.com/AFNetworking/AFNetworking/blob/master/AFNetworking/AFHTTPClient.m
相同