Objective c 使用Reactivecocoa刷新OAuth令牌
所以我想做的就是这样Objective c 使用Reactivecocoa刷新OAuth令牌,objective-c,reactive-cocoa,Objective C,Reactive Cocoa,所以我想做的就是这样 发出包含指定授权令牌的标头的HTTP请求 如果响应是401 Unauthorized,我希望使用我的刷新令牌获取新的访问令牌和新的刷新令牌 当我拥有新的令牌对时,我希望使用新的令牌重试失败的请求 我看了这篇文章就知道了。他们是这样解决的 - (RACSignal *)doRequestAndRefreshTokenIfNecessary:(RACSignal *)requestSignal { return [requestSignal catch:^(NSEr
- 发出包含指定授权令牌的标头的HTTP请求
- 如果响应是401 Unauthorized,我希望使用我的刷新令牌获取新的访问令牌和新的刷新令牌
- 当我拥有新的令牌对时,我希望使用新的令牌重试失败的请求
- (RACSignal *)doRequestAndRefreshTokenIfNecessary:(RACSignal *)requestSignal {
return [requestSignal catch:^(NSError *error) {
// Catch the error, refresh the token, and then do the request again.
BOOL hasRefreshToken = [UserManager sharedInstance].refreshToken != nil;
BOOL httpCode401AccessDenied = error.code == -1011;
if (httpCode401AccessDenied && hasRefreshToken) {
return [[[self refreshToken] ignoreValues] concat:requestSignal];
}
return requestSignal;
}];
}
但问题是。如果我使用过期的访问令牌触发多个请求,有时会导致出现多次刷新的竞争条件
所以我认为我可以将刷新信号保存为一个实例变量,然后将所有后续失败的请求“链接”到该实例变量。但结果是刷新信号被多次执行
- (RACSignal *) refreshToken {
NSDictionary *params = @{
@"client_id": [Config clientId],
@"client_secret": [Config clientSecret],
@"grant_type": @"refresh",
@"refresh_token": [[Tokens sharedTokens] refreshToken]
};
if (self.activeRefreshSignal == nil) {
@weakify(self)
self.activeRefreshSignal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
@strongify(self)
[[RestAPI sharedClient] POST:@"/oauth/token"
parameters:params
success:^(NSURLSessionDataTask *operation, id responseObject) {
[self extractTokensFromResponseObject:responseObject];
[subscriber sendNext:nil];
[subscriber sendCompleted];
self.activeRefreshSignal = nil;
}
failure:^(NSURLSessionDataTask *operation, NSError *error) {
[[Tokens sharedTokens] clearTokens];
[subscriber sendError:error];
self.activeRefreshSignal = nil;
}];
return nil;
}];
}
return self.activeRefreshSignal;
}
-(RACSignal*)刷新令牌{
NSDictionary*参数=@{
@“客户端id:[Config clientId],
@“客户端密码”:[Config clientSecret],
@“授权类型”:@“刷新”,
@“刷新令牌”:[[Tokens sharedTokens]刷新令牌]
};
if(self.activeRefreshSignal==nil){
@weakify(自我)
self.activeRefreshSignal=[RACSignal createSignal:^RACDisposable*(id订户){
@强化(自我)
[[RestAPI sharedClient]POST:@/oauth/token”
参数:params
成功:^(NSURLSessionDataTask*操作,id responseObject){
[从responseObject:responseObject中自提取令牌];
[用户发送下一步:无];
[用户发送完成];
self.activeRefreshSignal=nil;
}
失败:^(NSURLSessionDataTask*操作,NSError*错误){
[[Tokens sharedTokens]clearTokens];
[订户发送错误:错误];
self.activeRefreshSignal=nil;
}];
返回零;
}];
}
返回自激活刷新信号;
}
有没有办法避免比赛状态,只刷新一次 你有没有找到解决这个问题的办法,安德烈亚斯?