来自用户名和密码的基本身份验证 header 在 AFNetworking 2.0 中不起作用
Basic auth header from username and password is not working In AFNetworking 2.0
我正在调用 A API 其所需的授权 header。
这是 API 给定 URL
的需要
用户名:testingyouonit@gmail.com
密码:testingyouonit2
创建授权header
第 1 步 - 对给定的密码进行 base64 编码。
第 2 步 - 对第 1 步中获得的密码进行 SHA256 哈希处理
步骤 3 - 使用在步骤 2 中获得的密码和给定的用户名创建授权 header
现在我正在使用 AFNetworking 传递请求
NSString *email=@"testingyouonit@gmail.com";
NSString *password=[self encodeStringTo64:@"testingyouonit2"];
我在这里编码了我的密码
- (NSString*)encodeStringTo64:(NSString*)fromString
{
NSData *plainData = [fromString dataUsingEncoding:NSUTF8StringEncoding];
NSString *base64String;
if ([plainData respondsToSelector:@selector(base64EncodedStringWithOptions:)]) {
base64String = [plainData base64EncodedStringWithOptions:kNilOptions];
} else {
base64String = [plainData base64Encoding];
}
return base64String;
}
现在我正在传递 GET 请求
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer = [AFJSONResponseSerializer serializer];
[manager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Accept"];
[manager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
manager.requestSerializer = [AFHTTPRequestSerializer serializer];
[manager.requestSerializer setAuthorizationHeaderFieldWithUsername:email password:password];
[manager.requestSerializer setValue:@"CAS256" forHTTPHeaderField:@"Authorization"];
[manager GET:@"https://myurlhere/youit" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"JSON: %@", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Error: %@", error);
}];
现在每次我收到这个
Error: Error Domain=com.alamofire.error.serialization.response Code=-1011 "Request failed: bad request (400)" UserInfo=0x7c361610 {com.alamofire.serialization.response.error.response=<NSHTTPURLResponse: 0x7aed9220> { URL: https://myurlhere/youit } { status code: 400, headers {
"Access-Control-Allow-Origin" = "*";
Connection = "keep-alive";
"Content-Length" = 114;
"Content-Type" = "application/json";
Date = "Sat, 11 Jul 2015 02:56:46 GMT";
Server = "nginx/1.1.19";
} }, NSErrorFailingURLKey=https://myurlhere/youit, NSLocalizedDescription=Request failed: bad request (400), com.alamofire.serialization.response.error.data=<7b0a2020 22657272 6f725f63 6f646522 3a202269 6e76616c 69645f61 7574685f 68656164 6572222c 0a202022 6d657373 61676522 3a202249 6e76616c 69642061 7574686f 72697a61 74696f6e 2e205573 6520616e 20617574 68206865 61646572 206f7220 61636365 73732068 61736822 0a7d>}
我在进行基本身份验证时犯的错误在哪里
您没有正确构建 header。请参阅 "client side" 部分 here。
顺便说一句,您收到错误 400,这意味着您的请求有误。如果这是一个安全问题,您将收到 401。因此,修复授权 header,但进一步查找您的请求的问题。
让我们创建 SHA256 并为其传递密码并尝试一下
NSString *email=@"testingyouonit@gmail.com";
NSString *password=[self encodeStringTo64:@"testingyouonit2"];
增加一种生成Sha256密码并传入请求的方法
第一步使用此方法需要#include <CommonCrypto/CommonDigest.h>
-(NSString*)sha256HashFor:(NSString*)input
{
const char* str = [input UTF8String];
unsigned char result[CC_SHA256_DIGEST_LENGTH];
CC_SHA256(str, strlen(str), result);
NSMutableString *ret = [NSMutableString stringWithCapacity:CC_SHA256_DIGEST_LENGTH*2];
for(int i = 0; i<CC_SHA256_DIGEST_LENGTH; i++)
{
[ret appendFormat:@"%02x",result[i]];
}
return ret;
}
并称之为
注意:在此处传递您使用的编码密码
NSString *password=[self encodeStringTo64:@"testingyouonit2"];
`password=[self sha256HashFor: password];`
最后一步
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer = [AFJSONResponseSerializer serializer];
[manager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Accept"];
[manager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
manager.requestSerializer = [AFHTTPRequestSerializer serializer];
[manager.requestSerializer setAuthorizationHeaderFieldWithUsername:email password:password];
[manager GET:@"https://myurlhere/youit" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"JSON: %@", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Error: %@", error);
}];
让我看看结果
试试下面的代码
NSString *URLString = @"url";
NSData *data = [NSJSONSerialization dataWithJSONObject:parameters options:NSJSONWritingPrettyPrinted error:nil];
NSString *jsonStr = [[NSString alloc] initWithData:data
encoding:NSUTF8StringEncoding];
NSString *username = [[NSUserDefaults standardUserDefaults] objectForKey:@"userName"];
NSString *password = [[NSUserDefaults standardUserDefaults] objectForKey:@"password"];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSURLCredential *credential = [NSURLCredential credentialWithUser:username password:password persistence:NSURLCredentialPersistenceNone];
NSString *authenticationString = [NSString stringWithFormat:@"%@:%@", username, password];
NSData *authenticationData = [authenticationString dataUsingEncoding:NSASCIIStringEncoding];
NSString *authenticationValue = [authenticationData base64EncodedStringWithOptions:0];
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:URLString] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:20.0f];
[theRequest setHTTPMethod:@"POST"];
[theRequest setValue:[NSString stringWithFormat:@"Basic %@", authenticationValue] forHTTPHeaderField:@"Authorization"];
[theRequest setValue:@"application/json" forHTTPHeaderField:@"Accept"];
[theRequest setValue:@"application/json; charset=UTF-8" forHTTPHeaderField:@"Content-Type"];
[theRequest setHTTPBody:[jsonStr dataUsingEncoding:NSUTF8StringEncoding]];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:theRequest];
[operation setCredential:credential];
[operation setResponseSerializer:[AFJSONResponseSerializer alloc]];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"Success: %@", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Failure: %@", error);
}];
[manager.operationQueue addOperation:operation];
对于使用 AFNetworking 3.x 的人,这里是对我有用的完整解决方案。
此代码发送具有基本身份验证的文件。只需更改 url、电子邮件和密码。
NSString *serverUrl = [NSString stringWithFormat:@"http://www.yoursite.com/uploadlink", profile.host];
NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] requestWithMethod:@"POST" URLString:serverUrl parameters:nil error:nil];
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
// Forming string with credentials 'myusername:mypassword'
NSString *authStr = [NSString stringWithFormat:@"%@:%@", email, emailPassword];
// Getting data from it
NSData *authData = [authStr dataUsingEncoding:NSASCIIStringEncoding];
// Encoding data with base64 and converting back to NSString
NSString* authStrData = [[NSString alloc] initWithData:[authData base64EncodedDataWithOptions:NSDataBase64EncodingEndLineWithLineFeed] encoding:NSASCIIStringEncoding];
// Forming Basic Authorization string Header
NSString *authValue = [NSString stringWithFormat:@"Basic %@", authStrData];
// Assigning it to request
[request setValue:authValue forHTTPHeaderField:@"Authorization"];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
NSURL *filePath = [NSURL fileURLWithPath:[url path]];
NSURLSessionUploadTask *uploadTask = [manager uploadTaskWithRequest:request fromFile:filePath progress:^(NSProgress * _Nonnull uploadProgress) {
// This is not called back on the main queue.
// You are responsible for dispatching to the main queue for UI updates
dispatch_async(dispatch_get_main_queue(), ^{
//Update the progress view
LLog(@"progres increase... %@ , fraction: %f", uploadProgress.debugDescription, uploadProgress.fractionCompleted);
});
} completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
if (error) {
NSLog(@"Error: %@", error);
} else {
NSLog(@"Success: %@ %@", response, responseObject);
}
}];
[uploadTask resume];
我正在调用 A API 其所需的授权 header。
这是 API 给定 URL
的需要用户名:testingyouonit@gmail.com
密码:testingyouonit2
创建授权header
第 1 步 - 对给定的密码进行 base64 编码。
第 2 步 - 对第 1 步中获得的密码进行 SHA256 哈希处理
步骤 3 - 使用在步骤 2 中获得的密码和给定的用户名创建授权 header
现在我正在使用 AFNetworking 传递请求
NSString *email=@"testingyouonit@gmail.com";
NSString *password=[self encodeStringTo64:@"testingyouonit2"];
我在这里编码了我的密码
- (NSString*)encodeStringTo64:(NSString*)fromString
{
NSData *plainData = [fromString dataUsingEncoding:NSUTF8StringEncoding];
NSString *base64String;
if ([plainData respondsToSelector:@selector(base64EncodedStringWithOptions:)]) {
base64String = [plainData base64EncodedStringWithOptions:kNilOptions];
} else {
base64String = [plainData base64Encoding];
}
return base64String;
}
现在我正在传递 GET 请求
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer = [AFJSONResponseSerializer serializer];
[manager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Accept"];
[manager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
manager.requestSerializer = [AFHTTPRequestSerializer serializer];
[manager.requestSerializer setAuthorizationHeaderFieldWithUsername:email password:password];
[manager.requestSerializer setValue:@"CAS256" forHTTPHeaderField:@"Authorization"];
[manager GET:@"https://myurlhere/youit" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"JSON: %@", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Error: %@", error);
}];
现在每次我收到这个
Error: Error Domain=com.alamofire.error.serialization.response Code=-1011 "Request failed: bad request (400)" UserInfo=0x7c361610 {com.alamofire.serialization.response.error.response=<NSHTTPURLResponse: 0x7aed9220> { URL: https://myurlhere/youit } { status code: 400, headers {
"Access-Control-Allow-Origin" = "*";
Connection = "keep-alive";
"Content-Length" = 114;
"Content-Type" = "application/json";
Date = "Sat, 11 Jul 2015 02:56:46 GMT";
Server = "nginx/1.1.19";
} }, NSErrorFailingURLKey=https://myurlhere/youit, NSLocalizedDescription=Request failed: bad request (400), com.alamofire.serialization.response.error.data=<7b0a2020 22657272 6f725f63 6f646522 3a202269 6e76616c 69645f61 7574685f 68656164 6572222c 0a202022 6d657373 61676522 3a202249 6e76616c 69642061 7574686f 72697a61 74696f6e 2e205573 6520616e 20617574 68206865 61646572 206f7220 61636365 73732068 61736822 0a7d>}
我在进行基本身份验证时犯的错误在哪里
您没有正确构建 header。请参阅 "client side" 部分 here。
顺便说一句,您收到错误 400,这意味着您的请求有误。如果这是一个安全问题,您将收到 401。因此,修复授权 header,但进一步查找您的请求的问题。
让我们创建 SHA256 并为其传递密码并尝试一下
NSString *email=@"testingyouonit@gmail.com";
NSString *password=[self encodeStringTo64:@"testingyouonit2"];
增加一种生成Sha256密码并传入请求的方法
第一步使用此方法需要#include <CommonCrypto/CommonDigest.h>
-(NSString*)sha256HashFor:(NSString*)input
{
const char* str = [input UTF8String];
unsigned char result[CC_SHA256_DIGEST_LENGTH];
CC_SHA256(str, strlen(str), result);
NSMutableString *ret = [NSMutableString stringWithCapacity:CC_SHA256_DIGEST_LENGTH*2];
for(int i = 0; i<CC_SHA256_DIGEST_LENGTH; i++)
{
[ret appendFormat:@"%02x",result[i]];
}
return ret;
}
并称之为
注意:在此处传递您使用的编码密码
NSString *password=[self encodeStringTo64:@"testingyouonit2"];
`password=[self sha256HashFor: password];`
最后一步
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer = [AFJSONResponseSerializer serializer];
[manager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Accept"];
[manager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
manager.requestSerializer = [AFHTTPRequestSerializer serializer];
[manager.requestSerializer setAuthorizationHeaderFieldWithUsername:email password:password];
[manager GET:@"https://myurlhere/youit" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"JSON: %@", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Error: %@", error);
}];
让我看看结果
试试下面的代码
NSString *URLString = @"url";
NSData *data = [NSJSONSerialization dataWithJSONObject:parameters options:NSJSONWritingPrettyPrinted error:nil];
NSString *jsonStr = [[NSString alloc] initWithData:data
encoding:NSUTF8StringEncoding];
NSString *username = [[NSUserDefaults standardUserDefaults] objectForKey:@"userName"];
NSString *password = [[NSUserDefaults standardUserDefaults] objectForKey:@"password"];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSURLCredential *credential = [NSURLCredential credentialWithUser:username password:password persistence:NSURLCredentialPersistenceNone];
NSString *authenticationString = [NSString stringWithFormat:@"%@:%@", username, password];
NSData *authenticationData = [authenticationString dataUsingEncoding:NSASCIIStringEncoding];
NSString *authenticationValue = [authenticationData base64EncodedStringWithOptions:0];
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:URLString] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:20.0f];
[theRequest setHTTPMethod:@"POST"];
[theRequest setValue:[NSString stringWithFormat:@"Basic %@", authenticationValue] forHTTPHeaderField:@"Authorization"];
[theRequest setValue:@"application/json" forHTTPHeaderField:@"Accept"];
[theRequest setValue:@"application/json; charset=UTF-8" forHTTPHeaderField:@"Content-Type"];
[theRequest setHTTPBody:[jsonStr dataUsingEncoding:NSUTF8StringEncoding]];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:theRequest];
[operation setCredential:credential];
[operation setResponseSerializer:[AFJSONResponseSerializer alloc]];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"Success: %@", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Failure: %@", error);
}];
[manager.operationQueue addOperation:operation];
对于使用 AFNetworking 3.x 的人,这里是对我有用的完整解决方案。 此代码发送具有基本身份验证的文件。只需更改 url、电子邮件和密码。
NSString *serverUrl = [NSString stringWithFormat:@"http://www.yoursite.com/uploadlink", profile.host];
NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] requestWithMethod:@"POST" URLString:serverUrl parameters:nil error:nil];
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
// Forming string with credentials 'myusername:mypassword'
NSString *authStr = [NSString stringWithFormat:@"%@:%@", email, emailPassword];
// Getting data from it
NSData *authData = [authStr dataUsingEncoding:NSASCIIStringEncoding];
// Encoding data with base64 and converting back to NSString
NSString* authStrData = [[NSString alloc] initWithData:[authData base64EncodedDataWithOptions:NSDataBase64EncodingEndLineWithLineFeed] encoding:NSASCIIStringEncoding];
// Forming Basic Authorization string Header
NSString *authValue = [NSString stringWithFormat:@"Basic %@", authStrData];
// Assigning it to request
[request setValue:authValue forHTTPHeaderField:@"Authorization"];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
NSURL *filePath = [NSURL fileURLWithPath:[url path]];
NSURLSessionUploadTask *uploadTask = [manager uploadTaskWithRequest:request fromFile:filePath progress:^(NSProgress * _Nonnull uploadProgress) {
// This is not called back on the main queue.
// You are responsible for dispatching to the main queue for UI updates
dispatch_async(dispatch_get_main_queue(), ^{
//Update the progress view
LLog(@"progres increase... %@ , fraction: %f", uploadProgress.debugDescription, uploadProgress.fractionCompleted);
});
} completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
if (error) {
NSLog(@"Error: %@", error);
} else {
NSLog(@"Success: %@ %@", response, responseObject);
}
}];
[uploadTask resume];