【问题标题】:Authentication with NSURLConnection sendAsynchronousRequest with completion handler使用完成处理程序使用 NSURLConnection sendAsynchronousRequest 进行身份验证
【发布时间】:2012-10-01 10:31:54
【问题描述】:

一般来说,我喜欢使用完成处理程序块使用 NSURL 的 sendAsynchronousRequest 类方法“触发并忘记”,但当需要身份验证时,这似乎不是一个选项。

当使用这样的完成处理程序样式请求时:

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


                            //Do Stuff   

                           }];

处理身份验证的正确方法是什么?我是否需要分配和初始化 NSURLConnection 并设置委托而不是使用此类方法样式?我想我了解如何使用委托函数正确进行身份验证,但我试图弄清楚是否可以将其包含在 completionHandler 块中,或者是否有更好的方法来做到这一点。

- (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];
    }

}

【问题讨论】:

    标签: ios authentication nsurlconnection


    【解决方案1】:

    我认为completionHandler 方法是针对基本请求的。也许您可以考虑使用AFNetworking,因为我将它与块方法和身份验证一起使用。

    编辑.... 您是否尝试将身份验证标头添加到 NSURLRequest? 创建一个 NSMutableURLRequest:

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

    并像这样添加身份验证标头:

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

    AFBase64EncodedStringFromString 函数是这样的:

    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];
    }
    

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

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

    【讨论】:

    • AFBase64EncodedStringFromString 是一个私有函数,不打算单独使用。相反,您可以使用AFHTTPClient setAuthorizationHeaderWithUsername:password: 并使用-requestWithMethod:path:parameters: 创建一个NSURLRequest(或者简单地从生成的请求中复制授权标头。
    【解决方案2】:

    尽管问题已经解决了一段时间,但我想添加一个不需要 3rd 方库的解决方案:

    //HTTP Authentication
    NSString *authStr = [NSString stringWithFormat:@"%@:%@", @"Username", @"Password"]];
    NSData *authData = [authStr dataUsingEncoding:NSASCIIStringEncoding];
    NSString *authValue = [authData base64Encoding];
    
    //Set up Request:
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc]init];
    [request setURL:[NSURL URLWithString:url]];
    //...
    // Pack in the user credentials
    [request setValue:[NSString stringWithFormat:@"Basic %@",authValue] forHTTPHeaderField:@"Authorization"];
    
    // Send the asynchronous request as usual
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *responseCode, NSData *responseData, NSError *error) {
    
        // Do stuff..
    
    }
    

    【讨论】:

    【解决方案3】:
    NSURLConnection is deprecated in iOS 9, try this code which is from LazyTableImages example from here [https://developer.apple.com/library/ios/samplecode/LazyTableImages/Introduction/Intro.html][1]
    
        @property (nonatomic, strong) NSURLSessionDataTask *sessionTask;
    
    
    
        //somwere in your code
    
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc]
                                        initWithURL:[NSURL URLWithString:self.postLink] ];
    
        [request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
        [request setHTTPShouldHandleCookies:NO];
        [request setTimeoutInterval:60];
        [request setHTTPMethod:@"POST"];
        [request addValue:[[NSUserDefaults standardUserDefaults] objectForKey:@"token"]
       forHTTPHeaderField:@"ACCESSTOKEN"];
    
    
        self.sessionTask = [[NSURLSession sharedSession] dataTaskWithRequest:request
                                                               completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        //do completion staff here
        }];
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-01-18
      • 1970-01-01
      • 2011-06-27
      • 1970-01-01
      • 2014-01-22
      • 1970-01-01
      • 1970-01-01
      • 2019-05-29
      相关资源
      最近更新 更多