验证与NSURLConnection的sendAsynchronousRequest与完成处理 [英] Authentication with NSURLConnection sendAsynchronousRequest with completion handler

查看:225
本文介绍了验证与NSURLConnection的sendAsynchronousRequest与完成处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一般来说,我想只是射后不理使用完成处理程序块与NSURL的sendAsynchronousRequest类的方法,但它似乎需要身份验证时,可能不是一个选项。

在使用这样的完成处理风格的请求:

  [NSURLConnection的sendAsynchronousRequest:[的NSURLRequest requestWithURL:[NSURL URLWithString:@http://www.mysite.com/]]
                                       队列:[NSOperationQueue mainQueue]
                           completionHandler:^(NSURLResponse *响应,NSData的*数据,NSError *错误){
                            //做东西                           }];

什么是处理身份验证的正确方法?我需要的alloc和init的NSURLConnection的,并设置一个委托,而不是使用这个类的方法做的风格的?我想我明白如何与委托功能正确验证,但我想弄清楚,如果我可以包括在completionHandler块或者是否有更好的方式来做到这一点。

   - (无效)连接:(NSURLConnection的*)连接willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)的挑战
{    如果([挑战previousFailureCount] 0){
        的NSLog(@验证失败);
        [连接取消]
    }
    其他
    {        NSURLCredential *证书= [NSURLCredential credentialWithUser:self.username
                                                                 密码:self.password
                                                              持久性:NSURLCredentialPersistenceForSession];
        [挑战发件人] useCredential:凭证forAuthenticationChallenge:挑战]
    }}


解决方案

我觉得completionHandler方法是基本要求。也许因为我用这个与块的方法和认证,你可以考虑使用 AFNetworking

编辑....
您是否尝试过添加认证头到的NSURLRequest?
创建一个NSMutableURLRequest:

  NSMutableURLRequest *的URLRequest = [[NSMutableURLRequest页头] initWithURL:[NSURL URLWithString:@http://www.mysite.com/]];

和添加认证头是这样的:

 的NSString * basicAuthCredentials = [的NSString stringWithFormat:@%@:%@,用户名,密码]
* NSString的authValue = [的NSString stringWithFormat:@基本%@,AFBase64En codedStringFromString(basicAuthCredentials)];
[的URLRequest的setValue:authValue forHTTPHeaderField:@授权];

该AFBase64En codedStringFromString功能是这样的:

 静态的NSString * AFBase64En codedStringFromString(的NSString *字符串){
    NSData的*数据= [NSData的dataWithBytes:[字符串UTF8字符串]长:[字符串lengthOfBytesUsingEncoding:NSUTF8StringEncoding]];
    NSUInteger长度= [数据长度]
    NSMutableData * mutableData = [NSMutableData dataWithLength:((长+ 2)/ 3)* 4];    uint8_t有*输入=(uint8_t有*)[数据字节]
    uint8_t有*输出=(uint8_t有*)[mutableData mutableBytes]    对于(NSUInteger我= 0; I<长度;我+ = 3){
        NSUInteger值= 0;
        为(NSUInteger J =; J&下;第(i + 3); J ++){
            值<< = 8;
            如果(J<长度){
                值| =(0xFF的&安培;输入[J]);
            }
        }        静态常量uint8_t有kAFBase64EncodingTable [] =ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 + /;        NSUInteger IDX =(I / 3)* 4;
        输出[IDX + 0] = kAFBase64EncodingTable [(价值>> 18)及0x3F的];
        输出[IDX + 1] = kAFBase64EncodingTable [(价值>> 12)及0x3F的];
        输出[IDX + 2] =第(i + 1) - ;长度 ? kAFBase64EncodingTable [(价值>> 6)及0x3F的]:'=';
        输出[IDX + 3] =(I + 2)下;长度 ? kAFBase64EncodingTable [(值GT;大于0)及0x3F的]:'=';
    }    返回[[的NSString页头] initWithData:mutableData编码:NSASCIIStringEncoding];
}

然后调用之前调用的函数,但使用新的NSURLRequest:

  [NSURLConnection的sendAsynchronousRequest:的URLRequest
                                       队列:[NSOperationQueue mainQueue]
                           completionHandler:^(NSURLResponse *响应,NSData的*数据,NSError *错误){
                            //做东西                           }];

Generally I like to just "fire and forget" with NSURL's sendAsynchronousRequest class method using the completion handler block but it seems that might not be an option when authentication is needed.

When using a completion handler style request like this:

[NSURLConnection sendAsynchronousRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.mysite.com/"]]
                                       queue:[NSOperationQueue mainQueue]
                           completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {


                            //Do Stuff   

                           }];

What is the proper way to handle authentication? Do I need to alloc and init the NSURLConnection and set a delegate instead of doing using this class method style? I think I understand how to authenticate correctly with the delegate function but I'm trying to figure out if I can include that in the completionHandler block or if there is a better way to do this.

- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{

    if ([challenge previousFailureCount] > 0) {
        NSLog(@"Authentication Failure");
        [connection cancel];
    }
    else
    {

        NSURLCredential *credential = [NSURLCredential credentialWithUser:self.username
                                                                 password:self.password
                                                              persistence:NSURLCredentialPersistenceForSession];
        [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
    }

}

解决方案

I think the completionHandler method is for basic requests. Maybe you could consider using AFNetworking as I use this with block methods and authentication.

EDIT.... Have you tried adding the authentication header to the NSURLRequest? Create an NSMutableURLRequest:

NSMutableURLRequest *urlRequest = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://www.mysite.com/"]];

And add the authentication header like this:

NSString *basicAuthCredentials = [NSString stringWithFormat:@"%@:%@", userName, password];
NSString *authValue = [NSString stringWithFormat:@"Basic %@", AFBase64EncodedStringFromString(basicAuthCredentials)];
[urlRequest setValue:authValue forHTTPHeaderField:@"Authorization"];

The AFBase64EncodedStringFromString function is this:

static NSString * AFBase64EncodedStringFromString(NSString *string) {
    NSData *data = [NSData dataWithBytes:[string UTF8String] length:[string lengthOfBytesUsingEncoding:NSUTF8StringEncoding]];
    NSUInteger length = [data length];
    NSMutableData *mutableData = [NSMutableData dataWithLength:((length + 2) / 3) * 4];

    uint8_t *input = (uint8_t *)[data bytes];
    uint8_t *output = (uint8_t *)[mutableData mutableBytes];

    for (NSUInteger i = 0; i < length; i += 3) {
        NSUInteger value = 0;
        for (NSUInteger j = i; j < (i + 3); j++) {
            value <<= 8;
            if (j < length) {
                value |= (0xFF & input[j]);
            }
        }

        static uint8_t const kAFBase64EncodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

        NSUInteger idx = (i / 3) * 4;
        output[idx + 0] = kAFBase64EncodingTable[(value >> 18) & 0x3F];
        output[idx + 1] = kAFBase64EncodingTable[(value >> 12) & 0x3F];
        output[idx + 2] = (i + 1) < length ? kAFBase64EncodingTable[(value >> 6)  & 0x3F] : '=';
        output[idx + 3] = (i + 2) < length ? kAFBase64EncodingTable[(value >> 0)  & 0x3F] : '=';
    }

    return [[NSString alloc] initWithData:mutableData encoding:NSASCIIStringEncoding];
}

Then call the function you called before, but using your new NSURLRequest:

[NSURLConnection sendAsynchronousRequest:urlRequest
                                       queue:[NSOperationQueue mainQueue]
                           completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {


                            //Do Stuff   

                           }];

这篇关于验证与NSURLConnection的sendAsynchronousRequest与完成处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆