首页 » iOS编程(第4版) » iOS编程(第4版)全文在线阅读

《iOS编程(第4版)》21.3 认证信息

关灯直达底部

Web服务可以在返回HTTP响应时附带认证要求(authentication challenge),其作用是询问“HTTP请求的发起方是谁?”这时发起方应该提供相应的用户名和密码(即认证信息),只有当认证通过后,Web服务才会返回真正的HTTP响应。

当应用收到认证要求时,NSURLSession的委托会收到URLSession:task: didReceiveChallenge:completionHandler:消息,可以在该消息中发送用户名和密码,完成认证。

打开BNRCoursesViewController.m,更新fetchFeed方法,访问安全度更高的Big Nerd Ranch在线课程Web服务(注意将http改为https),代码如下:

- (void)fetchFeed

{

NSString *requestString =

@“http://bookapi.bignerdranch.com/courses.json”;

NSString *requestString =

@“https://bookapi.bignerdranch.com/private/courses.json”;

NSURL *url = [NSURL URLWithString:requestString];

NSURLRequest *req = [NSURLRequest requestWithURL:url];

下面需要在初始化BNRCoursesViewController时为NSURLSession设置委托。更新initWithStyle:方法,代码如下:

- (instancetype)initWithStyle:(UITableViewStyle)style

{

self = [super initWithStyle:style];

if (self) {

self.navigationItem.title = @“BNR Courses”;

NSURLSessionConfiguration *config =

[NSURLSessionConfiguration defaultSessionConfiguration];

_session = [NSURLSession sessionWithConfiguration:config

delegate:nil

delegateQueue:nil];

_session = [NSURLSession sessionWithConfiguration:config

delegate:self

delegateQueue:nil];

[self fetchFeed];

}

return self;

}

然后在BNRCoursesViewController.m的类扩展中,使BNRCoursesViewController遵守NSURLSessionDataDelegate协议:

@interface BNRCoursesViewController ()<NSURLSessionDataDelegate>

@property (nonatomic) NSURLSession *session;

@property (nonatomic, copy) NSArray *courses;

@end

构建并运行应用,Web服务会返回一条错误消息:未认证的访问请求(unauthorized access)。因此,Web服务不会返回任何数据,UITableView对象中也没有显示任何在线课程信息。

为了通过Web服务认证,需要实现NSURLSession收到认证要求的委托方法。该方法会提供一个Block对象,可以将认证信息传入这个Block对象,完成认证。

在BNRCoursesViewController.m中,实现URLSession:task:didReceiveChallenge: completionHandler:方法,处理Web服务的认证要求:

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task

didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge

completionHandler:

(void (^)(NSURLSessionAuthChallengeDisposition,

NSURLCredential *))completionHandler

{

NSURLCredential *cred = [NSURLCredential

credentialWithUser:@“BigNerdRanch”

password:@“AchieveNerdvana”

persistence:NSURLCredentialPersistenceForSession];

completionHandler(NSURLSessionAuthChallengeUseCredential, cred);

}

completionHandler有两个参数。第一个参数是认证类型,由于NSURLCredential对象中提供了用户名和密码,因此类型是NSURLSessionAuthChallengeUseCredential。第二个参数是认证信息,即NSURLCredential对象。以上代码使用NSURLCredential的工厂方法credentialWithUser:password:persistence:创建NSURLCredential对象,该方法需要提供用户名、密码和认证信息的有效期限(有效期限是一个枚举值)。

构建并运行应用,运行结果与之前的相同。但是现在应用访问的是安全度更高的Big Nerd Ranch在线课程Web服务。