如何更改 Moya 中的不记名令牌

Posted

技术标签:

【中文标题】如何更改 Moya 中的不记名令牌【英文标题】:How can I change the bearer token in Moya 【发布时间】:2018-02-06 18:16:44 【问题描述】:

文档显示了如何使目标需要不记名令牌,我就是这样做的

extension MyService: AccessTokenAuthorizable 
    var authorizationType: AuthorizationType 
        switch self 
        case .resetPassword, .postTextBook, .bookmarkBook, .getBookmarks, .logout, .verify:
            return .bearer
        default:
            return .none
        
    

然后它显示了如何向提供者添加令牌,我确实喜欢这样做

let token = "abc123"
let authPlugin = AccessTokenPlugin(tokenClosure: token)
let provider = MoyaProvider<MyService>(plugins: [authPlugin])

但是当令牌过期时,我该如何更改令牌? Moya 是否提供了一种方法来自动化这个过程,如果我得到一个禁止的 http 响应(意味着我没有被授权),它会自动请求一个令牌?

【问题讨论】:

【参考方案1】:

对于每个 API,身份验证/授权的实现细节可能完全不同。这就是Moya 不会为您处理身份验证的原因。

也就是说,实现您自己的身份验证/授权可以通过许多方式完成。这将取决于您的限制和/或偏好。到今天为止,您可以在Moya documentation 中找到一些很少概述的解决方案:

使用PluginType 将您的身份验证添加到请求中。但是认为如果需要,这可能会用于刷新令牌。您可能还需要拦截请求的完成以检测授权错误并应用您首选的恢复方案(例如,刷新令牌并重试调用)。 同样可以使用endpointClosure和/或requestClosure来实现。 也可以考虑实现AlamofireRequestAdapterRequestRetrier。根据您的需要,这可以使重试更容易。但是,在它们上,您将无法直接访问您的 TargetType,因此您可能需要找到一种方法来识别所需的不同身份验证方法(即您的 bearernone)。

一些对其文档的直接引用:

Plugins Endpoints Authentication Alamofire Automatic Validation

另外,我强烈鼓励任何人从Eilodon's Networking source code 学习/获得灵感。

【讨论】:

【参考方案2】:

对于更改/刷新令牌,我使用了这个

static func send(request: TargetType) -> PrimitiveSequence<SingleTrait, Response> 
return provider.rx.request(request)
    .retry(1)
    .observeOn(ConcurrentDispatchQueueScheduler.init(qos: .default))
    .filterSuccessfulStatusAndRedirectCodes()
    .retryWhen( (errorObservable: Observable<Error>) in
        errorObservable.flatMap( (error) -> Single<String> in
            if let moyaError: MoyaError = error as? MoyaError, let response: Response = moyaError.response 
                    if **check forbidden http responses here** 
                        return provider.rx.request(.refreshToken(*your refresh token here*))
                            .filterSuccessfulStatusCodes()
                            .mapString(atKeyPath: "*json path to new access token*")
                            .catchError  (_) in
                                logout()
                                throw error
                            
                            .flatMap( (newAccessToken) -> PrimitiveSequence<SingleTrait, String> in
                                changeAccessToken()
                                return Single.just(newAccessToken)
                            )
                    
            
            throw error
        )
    )


static func logout() 
    // logout action


static func changeAccessToken() 
   // set new access token

【讨论】:

以上是关于如何更改 Moya 中的不记名令牌的主要内容,如果未能解决你的问题,请参考以下文章

Angular 中的不记名令牌

OAuth 2 中的不记名令牌和 token_type 是啥?

邮递员中的不记名令牌

带有 Zeep 和 Python 的 SOAP 客户端中的不记名令牌授权标头

java - 如何从Java Spring Boot中的请求标头获取不记名令牌?

从 Spotify 请求访问令牌时出现错误“仅支持有效的不记名身份验证”