1
我有一個相當簡單的授權/身份驗證應用程序,並且需要一些關於如何處理授權生命週期的幫助。下面是它的JIST:iOS:使用NSURLSession進行身份驗證和令牌過期
- 用戶輸入他們的憑據登錄服務器用在鑰匙串
- 令牌處於「授權」頭用於每個後續的URL請求令牌並存儲響應(REST調用)
- 令牌最終到期,服務器將與401個狀態碼
- 迴應此時,用戶需要通過登錄畫面重新進行身份驗證,所以我們可以得到一個新的令牌,然後重試請求
下面是一些代碼,代表我現在可以提出的最好的代碼。
static NSString * _authorizationToken;
@implementation MyRestfulModel
+ (id) sharedRestfulModel
{
// singleton model shared across view controllers
static MyRestfulModel * _sharedModel = nil;
@synchronized(self) {
if (_sharedModel == nil)
_sharedModel = [[self init] alloc];
}
return _sharedModel;
}
+ (NSString *) authorizationToken
{
if (!_authorizationToken)
_authorizationToken = @"";
return _authorizationToken;
}
+ (void) setAuthorizationToken: (NSString *token)
{
_authorizationToken = token;
}
-(void) doSomeRestfulCall: (NSString *) restURL
completionHandler: (void (^)(NSData * data)) callback
{
// construct url path and request
NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:restURL];
[request setValue:MyRestfulModel.authorizationToken forHTTPHeaderField:@"Authorization"];
[[[NSURLSession sharedSession] dataTaskWithRequest: request
completionHandler:^(NSData *data, NSURLResponse * response, NSError * error) {
NSHTTPResponse * httpResponse = (NSHTTPResponse *) response;
if([httpResponse statusCode] == 401) { // WHAT TO DO HERE ?
dispatch_sync(dispatch_get_main_queue(), ^{
MyAppDelegate * delegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate];
[delegate showLoginViewController callback:^(NSString * username, NSString * newToken) {
// recreate the NSURLSession and NSURLConfiguration with the new token and retry
MyRestfulModel.authenticationToken = token;
[self doSomeRestfulCall:callback];
}];
}
return;
} else {
callback(data);
}
}] resume];
}
我希望做這樣使得視圖控制器從來不需要擔心重試呼叫由於令牌到期,所有可怕的會話處理和認證可以通過一個對象來完成。
我正在考慮嘗試使用NSURLSessionDelegate,但我無法弄清楚didReceiveChallenge部分w.r.t.彈出登錄視圖控制器。我正在考慮的另一個選擇是添加一個類似於完成處理程序的「retryHandler」,該程序將在用戶重新驗證後調用。