我在調用遠程Web API的應用程序中使用ReactiveCocoa。但是,在從給定的API主機獲取任何東西之前,應用程序必須提供用戶的憑證並檢索API令牌,然後用它來簽署後續請求。如何使用ReactiveCocoa在進行API調用之前透明地進行身份驗證?
我想抽象出這個身份驗證過程,以便它在我進行API調用時自動發生。假設我有一個包含用戶憑證的API客戶端類。
// getThing returns RACSignal yielding the data returned by GET /thing.
// if the apiClient instance doesn't already have a token, it must
// retrieve one before calling GET /thing
RAC(self.thing) = [apiClient getThing];
如何使用ReactiveCocoa透明導致第一(且僅第一)請求的API來檢索和,作爲一個副作用,安全存儲的API令牌是由任何後續請求之前?
這也是一個要求,我可以使用combineLatest:
(或類似)來啓動多個同時發生的請求,並且它們都會隱式地等待該標記被檢索。
RAC(self.tupleOfThisAndThat) = [RACSignal combineLatest:@[ [apiClient getThis], [apiClient getThat]]];
此外,如果檢索令牌的請求已經在飛行時的API調用情況下,即API調用必須等到取回令牌請求已完成。
我的部分解決方案如下:
的基本模式將是使用flattenMap:
映射其產生令牌,鑑於令牌,執行所需的請求,併產生的結果的信號的信號API調用。
假設一些方便的擴展NSURLRequest
:
- (RACSignal *)requestSignalWithURLRequest:(NSURLRequest *)urlRequest {
if ([urlRequest isSignedWithAToken])
return [self performURLRequest:urlRequest];
return [[self getToken] flattenMap:^ RACSignal * (id token) {
NSURLRequest *signedRequest = [urlRequest signedRequestWithToken:token];
assert([urlRequest isSignedWithAToken]);
return [self requestSignalWithURLRequest:signedRequest];
}
}
現在考慮的-getToken
認購實施。
- 在平凡的情況下,當已經檢索到令牌時,訂閱立即生成令牌。
- 如果尚未檢索到令牌,則訂閱將按照返回令牌的認證API調用進行。
- 如果身份驗證API調用正在運行,則應該可以安全地添加另一個觀察者,而不會導致通過線路重複身份驗證API調用。
但是我不知道該怎麼做。另外,如何以及在哪裏安全地存儲令牌?某種持久/可重複的信號?
真棒解釋。謝謝! – bvanderveen
你會如何處理註銷?或多個帳戶? –
@ColinBarrett每個人都需要自己的詳細答案 - 這只是上述問題的最簡單的解決方案。支持註銷可能涉及將tokenSignal放入容量爲1的RACReplaySubject中,以便您可以隨意向其中添加新的信號。多個賬戶將會是一個更大的變化,因爲想必API也需要更新。我很樂意在SO或GitHub上的一個新問題上更詳細地回答。 –