2016-01-22 359 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 
    } 
    } 
}