Moya: Plugins doesn't work with GET requests
Hello
I use Moya/RxSwift 2.0.8 and I’m trying to use plugins to implement authorization token in HTTP headers
For example API:
import Moya
enum Api {
case getRequest
}
extension Api: AuthorizedTargetType {
/// The target's base `URL`.
var baseURL: URL { return URL(string: "http://url.com")! }
/// The path to be appended to `baseURL` to form the full `URL`.
var path: String {
switch self {
case .getRequest:
return "/api/v1/services/book"
}
}
/// The HTTP method used in the request.
var method: Moya.Method {
switch self {
case .getRequest:
return .get
}
}
/// The parameters to be incoded in the request.
var parameters: [String: Any]? {
switch self {
case .getRequest:
return nil
}
}
/// The method used for parameter encoding.
var parameterEncoding: ParameterEncoding {
return URLEncoding.default
}
/// Provides stub data for use in testing.
var sampleData: Data {
switch self {
case .getRequest:
return "{\"records\": [{\"id\": 3,\"price\": 5000,\"service\": {\"id\": 2,\"title\": \"Предпусковые подогреватели\"},\"created\": \"2017-02-13T11:26:19.125243Z\",\"modified\": \"2017-02-13T12:25:01.328032Z\",\"discount\": 0.2,\"date\": \"2017-02-13\",\"user\": 2}],\"total\": 5000,\"discount_total\": 1000}".utf8Encoded
}
}
/// The type of HTTP task to be performed.
var task: Task {
switch self {
default:
return .request
}
}
/// Whether or not to perform Alamofire validation. Defaults to `false`.
var validate: Bool {
return false
}
var needsAuth: Bool {
switch self {
case .getRequest:
return true
default:
return true
}
}
}
// MARK: - Helpers
private extension String {
var urlEscaped: String {
return self.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)!
}
var utf8Encoded: Data {
return self.data(using: .utf8)!
}
}
With Plugin:
import Moya
struct AuthPlugin: PluginType {
let token: String?
func prepare(_ request: URLRequest, target: TargetType) -> URLRequest {
guard let token = token,
let target = target as? AuthorizedTargetType,
target.needsAuth
else {
return request
}
var request = request
request.addValue("Token " + token, forHTTPHeaderField: "Authorization")
return request
}
}
protocol AuthorizedTargetType: TargetType {
var needsAuth: Bool { get }
}
And working code
let provider = RxMoyaProvider<Api>(
plugins: [
AuthPlugin(token: "eb1b505e863token6274bdfbe23925d223"),
NetworkLoggerPlugin(verbose: true)])
provider.request(.getRequest)
.debug()
.filterSuccessfulStatusCodes()
.subscribe(onNext: { (response) in
print(response)
}, onDisposed: {
})
In log we can see this situation:
["Moya_Logger: [13/02/2017 18:40:06] Request: http://url.com/api/v1/services/book"]
["Moya_Logger: [13/02/2017 18:40:06] Request Headers: [\"Authorization\": \"Token eb1b505e8634d19a2ece786274bdfbe23925d223\"]"]
["Moya_Logger: [13/02/2017 18:40:06] HTTP Request Method: GET"]
["Moya_Logger: [13/02/2017 18:40:07] Response: <NSHTTPURLResponse: 0x78e81ad0> { URL: http://url.com/api/v1/services/book/ } { status code: 401, headers {\n Allow = \"GET, OPTIONS\";\n Connection = \"keep-alive\";\n \"Content-Type\" = \"application/json\";\n Date = \"Mon, 13 Feb 2017 15:48:35 GMT\";\n Server = \"nginx/1.9.9\";\n \"Transfer-Encoding\" = Identity;\n Vary = Accept;\n \"Www-Authenticate\" = Token;\n \"X-Frame-Options\" = SAMEORIGIN;\n} }"]
["{\"detail\":\"Учетные данные не были предоставлены.\"}"]
But token is not present in the headers
Hypertext Transfer Protocol
GET /api/v1/services/book/ HTTP/1.1\r\n
Host: url.com\r\n
Connection: keep-alive\r\n
Accept: */*\r\n
Accept-Encoding: gzip;q=1.0, compress;q=0.5\r\n
User-Agent: moyaTest/1.0 (test.moyaTest; build:1; iOS 10.2.0) Alamofire/4.3.0\r\n
Accept-Language: ru-RU;q=1.0, en-RU;q=0.9\r\n
\r\n
[Full request URI: http://url.com/api/v1/services/book/]
[HTTP request 2/2]
[Prev request in frame: 94914]
[Response in frame: 94930]
But POST requests are working properly.
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Comments: 15 (9 by maintainers)
@scottrhoyt Good idea on using https://httpbin.org 🙌
As seen in Charles:
And response from https://httpbin.org/get
I could not reproduce the case of not seeing the field in the request but seeing it in the response.