我的应用与后端服务器通信。在每个Web请求中,都会检查身份验证令牌是否有效。如果不是应用程序请求新令牌。这在第一个实例中工作正常。
但是现在我遇到了困难,即新令牌会在某个时间点传递。在此时间点到达之前,原始请求必须等待,必须通知repsective新的身份验证令牌可用且请求可以继续。
如何解决这个难题?进行身份验证令牌刷新的最佳方法是什么?
以下是我目前所做的事情:
#import <UIKit/UIKit.h>
@interface LoginViewController : UIViewController <UIScrollViewDelegate>
-(IBAction)sandbox;
@end
#import "ViewController.h"
#import "WebApi.h"
@interface LoginViewController ()
@end
@implementation LoginViewController
-(IBAction)sandbox {
// Call the web request, if the auth token is expired
// a new token shall be retrieved if allowed and proceed
// with the web-request
[[WebApi sharedInstance] sandbox];
}
@end
#import "AFHTTPRequestOperationManager.h"
#import "SingletonClass.h"
@interface WebApi : AFHTTPRequestOperationManager <SingletonDelegate>
@property (nonatomic, strong) SingletonClass *sshare;
+(WebApi*)sharedInstance;
-(void)sandbox;
-(void)refreshVilitToken;
@end
#import "WebApi.h"
#define kApiHost @"http://192.168.1.157"
@implementation WebApi
-(WebApi*)initWithBaseURL:url {
self = [super init];
if (self != nil) {
self.sshare = [SingletonClass sharedInstance];
}
return self;
}
+(WebApi*)sharedInstance
{
static WebApi *sharedInstance = nil;
static dispatch_once_t oncePredicate;
dispatch_once(&oncePredicate, ^{
sharedInstance = [[self alloc] initWithBaseURL:[NSURL URLWithString:kApiHost]];
});
return sharedInstance;
}
-(void)sandbox {
DLog(@"Sandbox call");
NSString *URLString = [NSString stringWithFormat:@"%@/public/foo/sandbox", kApiHost];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[self setAuthHeader:manager];
[manager GET:URLString parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
DLog(@"JSON: %@", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
DLog(@"Error: %@, responseString: %@", error, operation.responseString);
}];
}
-(void)setAuthHeader:(AFHTTPRequestOperationManager *)manager {
if (self.sshare.hasCredentialsExpired) { // if token is expired!
[self refreshToken]; // get a new token
self.sshare.delegate = self;
self.sshare.tokenInRefreshProcess = YES; // token retrieving is in process
// If new token is retrived the variable is set to NO
}
if (!self.sshare.tokenInRefreshProcess) { // if the new token is available, then ...
// How do I ensure that this is proceeded first if the token is available?
NSDictionary *access = self.sshare.getAccessCredentials;
DLog(@"Token: %@ and id %@", access[@"token"], access[@"id"]);
manager.securityPolicy.allowInvalidCertificates = YES;
manager.requestSerializer = [AFHTTPRequestSerializer serializer];
[manager.requestSerializer setAuthorizationHeaderFieldWithUsername:access[@"token"]
password:access[@"id"]];
}
}
-(void)refreshToken {
DLog(@"%@", self.sshare.database[@"foo"]);
NSString *URLString = [NSString stringWithFormat:@"%@/public/foo/token/%@/%@", kApiHost, [self.sshare authKey], self.sshare.database[@"foo"][@"foo_refesh"]];
DLog(@"URLString %@", URLString);
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager PUT:URLString parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
[self.sshare saveNewToken:responseObject];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
DLog(@"Error: %@, responseString: %@", error, operation.responseString);
}];
}
// delegate, but I strugle to use this for every request...
// I could place here the -(void)sandbox call, but then I can only
// call this method, I want that this works for every web-request
-(void)didRefreshToken {
DLog(@"DELEGATE :: did refresh Vilit token!!");
}