>

Moya 를 사용하여 API와 통신하고 있습니다. 많은 엔드 포인트의 경우 사용자 인증이 필요합니다 (즉, 베어러 토큰은 인증 헤더를 기반으로 함).

Moya 문서에서 여기 에서 승인 헤더와 베어러 토큰을 포함하는 방법을 찾았습니다.

그러나 이제 인증 토큰 새로 고침을 구현해야하는데 어떻게해야할지 모르겠습니다.

Moya의 Github에서 이 스레드 를 찾았습니다. 도움이 될 것 같지만 코드를 어디에 넣을 지 모르겠습니다. 답변 코드는 다음과 같습니다.

// (Endpoint<Target>, NSURLRequest -> Void) -> Void
static func endpointResolver<T>() -> MoyaProvider<T>.RequestClosure where T: TargetType {
    return { (endpoint, closure) in
        let request = endpoint.urlRequest!
        request.httpShouldHandleCookies = false
        if (tokenIsOK) {
            // Token is valid, so just resume the request and let AccessTokenPlugin set the Authentication header
            closure(.success(request))
            return
        }
        // authenticationProvider is a MoyaProvider<Authentication> for example
        authenticationProvider.request(.refreshToken(params)) { result in
            switch result {
                case .success(let response):
                    self.token = response.mapJSON()["token"]
                    closure(.success(request)) // This line will "resume" the actual request, and then you can use AccessTokenPlugin to set the Authentication header
                case .failure(let error):
                    closure(.failure(error)) //something went terrible wrong! Request will not be performed
            }
        }
    }
}

여기 내 Moya 제공 업체 수업이 있습니다 :

import Foundation
import Moya
enum ApiService {
    case signIn(email: String, password: String)
    case like(id: Int, type: String)
}
extension ApiService: TargetType, AccessTokenAuthorizable {
    var authorizationType: AuthorizationType {
        switch self {
        case .signIn(_, _):
            return .basic
        case .like(_, _):
            return .bearer
        }
    }
    var baseURL: URL {
        return URL(string: Constants.apiUrl)!
    }
    var path: String {
        switch self {
            case .signIn(_, _):
                return "user/signin"
            case .like(_, _):
                return "message/like"
        }
    }
    var method: Moya.Method {
        switch self {
            case .signIn, .like:
                return .post
        }
    }
    var task: Task {
        switch self {
            case let .signIn(email, password):
                return .requestParameters(parameters: ["email": email, "password": password], encoding: JSONEncoding.default)
            case let .like(id, type):
                return .requestParameters(parameters: ["messageId": id, "type": type], encoding: JSONEncoding.default)
        }
    }
    var sampleData: Data {
        return Data()
    }
    var headers: [String: String]? {
        return ["Content-type": "application/json"]
    }
}
private extension String {
    var urlEscaped: String {
        return addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)!
    }
    var utf8Encoded: Data {
        return data(using: .utf8)!
    }
}


응답 코드를 어디에 코드에 넣을까요? 뭔가 빠졌습니까?


  • 답변 # 1

    실제로,이 예는 약간 오래된 것입니다. 여기 새로운 것이 있습니다 :

    extension MoyaProvider {
        convenience init(handleRefreshToken: Bool) {
            if handleRefreshToken {
                self.init(requestClosure: MoyaProvider.endpointResolver())
            } else {
                self.init()
            }
        }
        static func endpointResolver() -> MoyaProvider<Target>.RequestClosure {
            return { (endpoint, closure) in
                //Getting the original request
                let request = try! endpoint.urlRequest()
                //assume you have saved the existing token somewhere                
                if (#tokenIsNotExpired#) {                   
                    // Token is valid, so just resume the original request
                    closure(.success(request))
                    return
                }
                //Do a request to refresh the authtoken based on refreshToken
                authenticationProvider.request(.refreshToken(params)) { result in
                    switch result {
                    case .success(let response):
                        let token = response.mapJSON()["token"]
                        let newRefreshToken = response.mapJSON()["refreshToken"]
                        //overwrite your old token with the new token
                        //overwrite your old refreshToken with the new refresh token
                        closure(.success(request)) // This line will "resume" the actual request, and then you can use AccessTokenPlugin to set the Authentication header
                    case .failure(let error):
                        closure(.failure(error)) //something went terrible wrong! Request will not be performed
                    }
                }
        }
    }
    
    

    사용법 :

    public var provider: MoyaProvider<SomeTargetType> = MoyaProvider(withRefreshToken: true)
    provider.request(...)
    
    

  • 이전 python - "typeerror - 지원되지 않는 피연산자 유형 :- 'list'및 'list'
  • 다음 java - 멀티 플레이어 난수 추측 게임 - 각 플레이어마다 난수를 생성하는 방법은 무엇입니까?