我需要有关如何在我的应用中处理oauth2令牌的建议。
我正在使用GRPC向我的API发出http请求,我的API与oauth2令牌相关联(它在1小时后过期)。
在启动每个请求之前,我检查令牌:
最新?启动networkRequest
过时了吗?启动refreshToken - >启动networkRequest
一切似乎都运作良好,但在某些情况下,我的客户"失去"令牌。
问题在于2个请求A& B在同一时间启动 ,如果令牌过时,他们都会刷新它。 我的服务器将生成一个newTokenA,返回它,生成newTokenB(删除newTokenA),返回它。 如果响应 newTokenA 在newTokenB 之后到达客户端,则客户端令牌令牌将不是好的。
我使用信号量来确保同时调用refreshToken。
但是当我的信号量等待时,我的服务器没有收到任何回复。
let semaphore: dispatch_semaphore_t = dispatch_semaphore_create(0)
func authenticate(completion: (GRPCProtoCall) -> (Void)) -> GRPCProtoCall {
// Wait here if authenticate already called
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)
// If token up to date
if isOAuth2TokenValid() {
dispatch_semaphore_signal(semaphore) // Release semaphore
completion(self.withAuthorization())
return self
}
// Refresh the outdated token
APIClient.shared.oAuth2AccessTokenRefresh { (response) -> (Void) in
dispatch_semaphore_signal(semaphore) // Release semaphore
completion(self.withAuthorization())
}
return self
}
答案 0 :(得分:1)
我认为你的SELECT MAX(CompletTime)
FROM Audit.T1 bb
WHERE [Status]= 'Loaded'
AND bb.IsFullLoad = 1
AND bb.TableName = bi.TableName
AND CompletTime < b1.CompletTime
持有你的线程,你可以尝试使用超时,但最后一个请求没有响应,并在返回自我之前把它放进去
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)
答案 1 :(得分:0)
首先,我建议为1
资源创建信号量,而不是0
(用于阅读目的):
let semaphore: dispatch_semaphore_t = dispatch_semaphore_create(0)
其次,我认为问题在于您首先释放信号量,然后调用完成块:执行以下操作:
// Refresh the outdated token
APIClient.shared.oAuth2AccessTokenRefresh { (response) -> (Void) in
completion(self.withAuthorization())
dispatch_semaphore_signal(semaphore) // Release semaphore at very end
}
答案 2 :(得分:0)
为什么不让方法完全异步? (self
似乎无处不在)
func authenticate(completion: (GRPCProtoCall) -> ()) {
// If token up to date
if isOAuth2TokenValid() {
completion(self.withAuthorization())
} else {
// Refresh the outdated token
APIClient.shared.oAuth2AccessTokenRefresh { response in
completion(self.withAuthorization())
}
}
}