【问题标题】:Using AFNetworking with authentication fails with correct credentials使用带有身份验证的 AFNetworking 失败,但凭据正确
【发布时间】:2013-05-08 15:25:07
【问题描述】:

我正在尝试使用 AFNetworking 从我公司的 FTP 站点下载 .sqlite 文件。每个 FTP 用户在我的服务器上都有自己的文件夹。我找到this question 处理身份验证,找到this question 处理下载。我相信我已经正确地将两者结合在一起以获得我正在寻找的东西(或者至少我还没有走得足够远来能够测试它)。无论如何,我已经在这里附加了我的代码。

AFHTTPClient 子类.h

#import "AFHTTPClient.h"

@interface AFNetworkingHelper : AFHTTPClient

- (void) setUsername:(NSString *)username andPassword:(NSString *)password;

+ (AFNetworkingHelper *)sharedManager;

@end

AFHTTPClient 子类.m

#import "AFNetworkingHelper.h"
@implementation AFNetworkingHelper

#pragma mark - Methods
- (void)setUsername:(NSString *)username andPassword:(NSString *)password
{
    [self clearAuthorizationHeader];
    [self setAuthorizationHeaderWithUsername:username password:password];
}

#pragma mark - Initialization
- (id) initWithBaseURL:(NSURL *)url
{
    self = [super initWithBaseURL:url];
    if (!self)
    {
        return nil;
    }

    return self;
}

#pragma mark - Singleton Methods
+ (AFNetworkingHelper *)sharedManager
{
    static dispatch_once_t pred;
    static AFNetworkingHelper *_sharedManager = nil;

    dispatch_once(&pred, ^{ _sharedManager = [[self alloc] initWithBaseURL:[NSURL URLWithString:@"ftp://www.mysite.net"]]; });
    return _sharedManager;
}

@end

ViewController.m

// Download data - AFNetworking method
[[AFNetworkingHelper sharedManager] setUsername:@"myusername" andPassword:@"mypassword"];
[[AFNetworkingHelper sharedManager] getPath:@"/myfile.sqlite" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject)
{
     NSURL *path = [[[app applicationDocumentsDirectory] URLByAppendingPathComponent:@"myfile"] URLByAppendingPathExtension:@"sqlite"];
     operation.outputStream = [NSOutputStream outputStreamWithURL:path append:NO];
     [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject)
     {
          NSLog(@"Successfully downloaded file to path: %@",path);
          // Update dates table to reflect that info was updated here
     }
                                     failure:^(AFHTTPRequestOperation *operation, NSError *error)
     {
           NSLog(@"Error in AFHTTPRequestOperation in clickedButtonAtIndex on myController.m");
           NSLog(@"%@",error.description);
      }];

      [operation start];
  }
                          failure:^(AFHTTPRequestOperation *operation, NSError *error)
  {
        NSLog(@"Error in AFHTTPRequestOperation in clickedButtonAtIndex on myController.m");
        NSLog(@"%@",error.description);
   }];

我遇到的问题是当我尝试运行它时得到一个NSURLErrorDomain Code=-1102 "You do not have permission to access the requested resource"。我已经确认我发送的用户名和密码是正确的。如果我尝试将路径传递给不存在的文件,我仍然会收到 -1102 错误(而不是说我请求的文件不存在的错误,这是我期望得到的错误)。如果我从链接到浏览器的第一个问题中输入path,我会根据我使用的浏览器得到一些不同的行为:

  • Firefox:我必须输入path,不带用户名,带文件(类似于ftp://www.mysite.net/myfile.sqlite)。当我在地址栏中输入这个时,我会弹出一个询问用户名和密码的窗口。当我输入正确的凭据时,文件下载开始并成功完成。
  • IE:我必须输入带有用户名和文件的path(类似于ftp://www.mysite.net/myuser/myfile.sqlite)。当我在地址栏中输入这个时,我会弹出一个询问用户名和密码的窗口。当我输入正确的凭据时,文件下载开始并成功完成。
  • Safari:无论我如何输入path,我都会得到一个错误屏幕,上面写着You don't have permission to open this page。我没有收到凭据提示,也没有开始下载。如果我尝试将path 输入到一个不存在的文件中,我仍然会收到错误消息You don't have permission to open this page(就像我尝试在我的应用程序中请求一个不存在的文件时一样)。更新:根据@rog 的评论使用“USERNAME:PASSWORD@www...”语法允许我在 Safari 中成功下载。

我真的不明白这里发生了什么。我是否从我的应用程序中收到错误消息,因为它实际上从未收到凭据挑战,例如当我尝试使用 Safari 打开它时?如果是这样,为什么我不像使用其他浏览器时那样从我的应用程序或 Safari 中收到对我的凭据的挑战?有没有办法检查我的应用在尝试下载文件时是否真的在尝试使用我提供的凭据?

【问题讨论】:

  • 发布您的代码! (省略您的凭据)。另外,请尝试使用 URL 架构:ftp://USERNAME:PASSWORD@mysite.net/myfile.sqlite
  • @rog:添加了代码。另外,我尝试了您建议的架构,它允许我使用 Safari 下载文件。由于pathmyController.mAFNetworkHelper.m 上的调用之间拆分,我该如何将其添加到我的应用程序中?

标签: ios browser windows-server-2003 afnetworking credentials


【解决方案1】:

FTPHTTP 是两个不同的协议

将 AFHTTPClient 用于 FTP 服务器是行不通的。 AFNetworking 只支持AFURLConnectionOperation 的FTP;其他一切都是 HTTP。

【讨论】:

  • @GeneralMike 纯属巧合。 NSURLConnection 恰好支持 FTP 和 HTTP。不了解差异最终会在某些时候给您带来问题。
【解决方案2】:

使用@rog 在他的评论中建议的语法,我能够调整我的问题(关于下载)中第二个链接中的代码以允许基本身份验证,并完全消除了将 AFHTTPClient 子类化的需要。这是我使用的(编辑的)代码:

NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"ftp://myUsername:myPassword@www.mysite.net/myfile.sqlite"]];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
NSURL *path = [[[app applicationDocumentsDirectory] URLByAppendingPathComponent:@"myfile"] URLByAppendingPathExtension:@"sqlite"];
operation.outputStream = [NSOutputStream outputStreamWithURL:path append:NO];

[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject)
    {
        NSLog(@"Successfully downloaded file to path: %@",path);
    }
                                 failure:^(AFHTTPRequestOperation *operation, NSError *error)
    {
        NSLog(@"Error in AFHTTPRequestOperation in clickedButtonAtIndex on FlightInfoController.m");
        NSLog(@"%@",error.description);
    }];

[operation start];

这实际上并没有让我更接近了解为什么使用 [[AFNetworkingHelper sharedManager] setUsername:@"myUsername" andPassword@"myPassword"]; 失败,但从好的方面来说,我从我的应用程序中获得了我想要的行为。我想我可以忍受这一点。

【讨论】:

    猜你喜欢
    • 2016-05-10
    • 1970-01-01
    • 2016-01-10
    • 1970-01-01
    • 2022-01-10
    • 1970-01-01
    • 2022-01-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多