如何连接到需要用户名和密码的网站

时间:2011-03-09 21:40:22

标签: iphone ios

我有一个基本问题,我希望有一个我错过的简单答案。基本前提是我要连接到一个网站并下载一些JSON数据。我正在使用Stig Brautaset提供的框架,该教程非常有效。

我的问题是我所连接的网站格式正确,我的应用程序的用户名和密码是固定的,因此用户永远不会输入它们。

curl -u username:password http://website.com/page

如何将网址和密码传递给NSURLConnection

它不一定是NSURLConnection,它似乎是最好的选择。

我查看了AdvancedUrlConnections样本,但它看起来过于复杂而且已经很老了。在网上搜索并没有好多少。我希望你们中的一个人能说出这两个属性,然后选择合适的侮辱......

2 个答案:

答案 0 :(得分:3)

NSURLConnection可以正常工作。正如另一个答案所指出的那样,实现didReceiveAuthenticationChallenge回调非常容易。

- (void) someMethod
{
    NSURLRequest* request = [[NSURLRequest alloc] 
         initWithURL:[NSURL urlWithString:@"someURL"]

    NSURLConnection* connection = [[NSURLConnection alloc] 
         initWithRequest:request delegate:self];

    [connection release];
    [request release];
}

这一切都非常直截了当。它位于NSURLConnection的委托方法中,所有的魔法都发生了:

这是您处理凭据挑战的地方。我已经硬编码了一个假的用户名和密码来演示它是如何工作的。我个人有一个单独的委托对象处理挑战。请记住,连接将处于空闲状态,直到您对其进行响应或连接超时为止。

- (void) connection:(NSURLConnection *)connection 
      didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
    //  Make sure to use the appropriate authentication method for the server to
    //  which you are connecting.
    if ([[challenge protectionSpace] authenticationMethod] == 
             NSURLAuthenticationMethodBasicAuth)
    {
            //  This is very, very important to check.  Depending on how your 
            //  security policies are setup, you could lock your user out of his 
            //  or her account by trying to use the wrong credentials too many 
            //  times in a row.
        if ([challenge previousFailureCount] > 0)
        {
            [[challenge sender] cancelAuthenticationChallenge:challenge];

            UIAlertView* alert = [[UIAlertView alloc] 
                            initWithTitle:@"Invalid Credentials" 
                                  message:@"The credentials are invalid." 
                                 delegate:nil 
                        cancelButtonTitle:@"OK" 
                        otherButtonTitles:nil];
            [alert show];
            [alert release];      
        }
        else
        {
            [challenge useCredential:[NSURLCredential 
                   credentialWithUser:@"someUser" 
                             password:@"somePassword" 
                          persistence:NSURLCredentialPersistenceForSession 
           forAuthenticationChallenge:challenge]];
        }
    }
    else
    {
        //  Do whatever you want here, for educational purposes, 
            //  I'm just going to cancel the challenge
        [[challenge sender] cancelAuthenticationChallenge:challenge];
    }
}

您还需要为NSURLConnection实现这些其他方法:

//  So you know when it's done downloading
- (void) connectionDidFinishLoading:(NSURLConnection *)connection;
//  In case of failure
- (void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error;    
//  Gather the downloaded file data
- (void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data;

答案 1 :(得分:0)

有几种可能性。

如果使用异步NSURLConnection,将在连接的委托上调用方法-connection:didReceiveAuthenticationChallenge:。该方法的文档解释了如何处理它。这是AdvancedUrlConnections使用的,是的,它有点混乱。

更简单的方法是在创建连接时创建NSMutableURLRequest(而不是不可变的NSURLRequest)。这允许您添加任意HTTP标头。构造一个基本的auth标头很简单 - 类似于

NSMutableURLRequest *request = .... // details omitted
NSString *username = // ....
NSString *password = // ....
NSData *authRawData = [[NSString stringWithFormat:@"%@:%@", username, password] dataUsingEncoding:NSUTF8StringEncoding];
NSString *authEncoded = [authRawData asBase64EncodedString];
[request setValue:[NSString stringWithFormat:@"Basic %@", authEncoded] forHTTPHeaderField:@"Authorization"];

以上使用TouchFoundation

中包含的-asBase64EncodedString方法