如何在午睡中覆盖某些资源的默认(“**”)装饰器?
Posted
技术标签:
【中文标题】如何在午睡中覆盖某些资源的默认(“**”)装饰器?【英文标题】:How to override default ("**") decorator for certain resource in siesta? 【发布时间】:2019-04-11 13:46:21 【问题描述】:我正在尝试在服务器上将 Siesta swift 包与我的 API 一起使用。我们已经使用访问和刷新令牌设置了 JWT 身份验证。我们可以通过刷新过程成功地进行身份验证并获取新的访问令牌。但是我们提出的解决方案让我看起来有点老套。
我们正在使用这样的请求装饰器
func init()
service.configure("**")
if let session = self.appSession
$0.headers["Authorization"] = "Bearer \(session.tokens.access)"
$0.decorateRequests
self.globalApiFailHandler(request: $1)
service.configure(authRefreshResource)
if let session = self.appSession
$0.headers["Authorization-Refresh"] = "Bearer \(session.tokens.refresh)"
$0.decorateRequests
self.refreshTokenFailure(request: $1)
private func globalApiFailHandler(request: Siesta.Request) -> Request
return request.chained //special case to Refresh Token On Auth Failure
if case
.failure(let error) = $0.response, // Did request fail…
error.httpStatusCode == 401, // …because of expired token?
self.appSession != nil // we have refreshToken
log.warning("Seems like Access Token is expired, Trying to refresh it!")
return .passTo(
self.refreshAuth().chained // 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.
)
if case
.failure(let error) = $0.response,
error.httpStatusCode != 409
log.warning("Something went wrong during request: \(error)")
self.retryLaterEvent() // TODO: Really need this here?
return .useThisResponse // If not, use the response we got.
private func refreshTokenFailure(request: Siesta.Request) -> Request
return request.chained
if case
.failure(let error) = $0.response // Did request fail…
log.error("Refresh token procedure failed with \(error).")
if error.httpStatusCode == 409
log.warning("409, Resetting app session storage! Relogin or app recreation is needed!")
self.relogin = true //Reset saved sessions to create new app
self.reloginEvent()
else
log.warning("Something went wrong during refresh token procedure. Please retry later!")
self.retryLaterEvent()
///let requestError = RequestError(userMessage: "Unable to refresh access token", cause: "")
let response = Response.failure(error) //(requestError)
let responseInfo = ResponseInfo(response: response)
return .useResponse(responseInfo) // If not, use the response we got.
return .useThisResponse // We have new token!
请注意409
返回代码检查globalApiFailHandler
。它在那里是因为全局装饰器总是为authRefreshResource
调用。如果我们忽略该检查,API 将在某些服务器错误下陷入无限循环刷新令牌。
问题是如何为我们想要的特定资源禁用全局装饰器?拥有它将优雅地解决我们的问题。
【问题讨论】:
【参考方案1】:您可以将任意谓词传递给configure(whenURLMatches:)
,这样您就可以外科手术般地排除您喜欢的任何东西:
service.configure(whenURLMatches: url in url.path != "/auth" )
...
或者,如果你想排除一个你有Resource
方便的URL:
service.configure(whenURLMatches: $0 != authRefreshResource.url )
...
【讨论】:
很好,谢谢!我们很快就会试一试!以上是关于如何在午睡中覆盖某些资源的默认(“**”)装饰器?的主要内容,如果未能解决你的问题,请参考以下文章
如何用 Jest 单元测试覆盖 TypeORM @Column 装饰器?