2016-01-22 357 views
2

我正在嘗試設置一個簡單的iOS示例以更好地瞭解Siesta。我的REST API需要一個訪問令牌來陪伴每個請求。所以(1)在應用程序的開始處,以及(2)任何時候我檢索一個HTTP 401,我需要請求一個訪問令牌,然後將其放入所有未來的授權頭中。身份驗證令牌

從文檔中找出這個例子,我假設包含showLoginScreen的行是我需要撥打我的authenticationResource來獲取令牌的地方,但是我應該如何在發生故障後立即進行調用(而不是無限循環) )?謝謝。

let authURL = authenticationResource.url 

configure({ url in url != authURL }, description: "catch auth failures") { 
    $0.config.beforeStartingRequest { _, req in // For all resources except auth: 
    req.onFailure { error in      // If a request fails... 
     if error.httpStatusCode == 401 {   // ...with a 401... 
     showLoginScreen()      // ...then prompt the user to log in 
     } 
    } 
    } 
} 
+0

你能澄清你所說的「我怎麼做的失敗的呼叫後,立即?」你是詢問如何調用authenticationResource,或約意思如何如果認證成功,重新嘗試產生401的呼叫? –

+0

是的,我該如何重新嘗試撥打電話。現在我在視圖控制器的開始處進行一次調用以獲取令牌,但我知道這是錯誤的,因爲我需要在同一視圖中再次獲取令牌(超時?)。因此,邏輯將是在休息電話之前總是檢查我是否有令牌,獲取令牌並重新嘗試。謝謝。 – user2199730

回答

1

由於您提出問題,文檔已更新爲an example that answers it

問題的關鍵是使用decorateRequests(…)Request.chained(…)來包裝所有服務的請求,以便它們在返回響應之前自動嘗試刷新令牌。

下面是從例子中的代碼:

authToken: String?? 

init() { 
    ... 
    configure("**", description: "auth token") { 
    if let authToken = self.authToken { 
     $0.headers["X-Auth-Token"] = authToken   // Set the token header from a var that we can update 
    } 
    $0.decorateRequests { 
     self.refreshTokenOnAuthFailure(request: $1) 
    } 
    } 
} 

// Refactor away this pyramid of doom however you see fit 
func refreshTokenOnAuthFailure(request: Request) -> Request { 
    return request.chained { 
    guard case .failure(let error) = $0.response, // Did request fail… 
     error.httpStatusCode == 401 else {   // …because of expired token? 
     return .useThisResponse     // If not, use the response we got. 
    } 

    return .passTo(
     self.createAuthToken().chained {    // If so, first request a new token, then: 
     if case .failure = $0.response {   // If token request failed… 
      return .useThisResponse     // …report that error. 
     } else { 
      return .passTo(request.repeated())  // We have a new token! Repeat the original request. 
     } 
     } 
    ) 
    } 
} 

func createAuthToken() -> Request { 
    return tokenCreationResource 
    .request(.post, json: userAuthData()) 
    .onSuccess { 
     self.authToken = $0.jsonDict["token"] as? String // Store the new token, then… 
     self.invalidateConfiguration()     // …make future requests use it 
    } 
    } 
}