#ios #swift #alamofire #urlrequest
Вопрос:
Я устанавливаю базовый токен аутентификации в свой URL-запрос и использую Alamofire для выполнения.
Я установил 3 заголовка, содержимое, принять и аутентификацию…содержимое и принятие видны в сетевом трафике, но аутентификация отсутствует. Он доступен, если я распечатаю заголовки URL-запроса перед его отправкой…
Есть какие-нибудь идеи? поскольку я не вижу, как удалить заголовок аутентификации перед публикацией
Код выглядит следующим образом:
// Construct url
let url = try APIConstants.baseUrl.asURL()
// Append path
var urlRequest = URLRequest(url: url.appendingPathComponent(path))
// Determine HTTP method
urlRequest.httpMethod = method.rawValue
let headers: HTTPHeaders = [
.contentType(APIConstants.ContentType.json.rawValue),
.accept(APIConstants.ContentType.json.rawValue),
]
if let token = token {
urlRequest.addValue("(APIConstants.API.token.rawValue) (token.key)",
forHTTPHeaderField: "Authorization")
}
urlRequest.headers = headers
// Add http body to request
if let parameters = parameters {
do {
let data = try JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted)
urlRequest.httpBody = data
} catch (_) {
print("APIRouter: Failed to parse body into request.")
}
}
//Encoding
let encoding: ParameterEncoding = {
switch method {
case .get:
return URLEncoding.default
default:
return JSONEncoding.default
}
}()
return try encoding.encode(urlRequest, with: parameters)
}
В моем клиенте rest я выполняю так:
return Observable<T>.create { observer in
let request = AF.request(urlConvertible).responseDecodable { (response: DataResponse<T, AFError>) in
switch response.result {
case .success(let value):
observer.onNext(value)
observer.onCompleted()
case .failure(let error):
switch response.response?.statusCode {
case 403:
observer.onError(APIError.forbidden)
case 404:
observer.onError(APIError.notFound)
case 409:
observer.onError(APIError.conflict)
case 500:
observer.onError(APIError.internalServerError)
default:
observer.onError(error)
}
}
}
return Disposables.create {
request.cancel()
}
}
}
Редактировать:
Обновлена функция, чтобы показать дальнейшую проблему:
func asURLRequest() throws -> URLRequest {
// Construct url
let url = try APIConstants.baseUrl.asURL()
// Append path
var urlRequest = URLRequest(url: url.appendingPathComponent(path))
// Determine HTTP method
urlRequest.httpMethod = method.rawValue
let headers: HTTPHeaders = [
.contentType(APIConstants.ContentType.json.rawValue),
.accept(APIConstants.ContentType.json.rawValue),
.authorization("Token a5555485aa251b28fdsfasdfdsb379c131fddad")
]
urlRequest.headers = headers
// Add http body to request
if let parameters = parameters {
do {
let data = try JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted)
urlRequest.httpBody = data
} catch (_) {
print("APIRouter: Failed to parse body into request.")
}
}
//Encoding
let encoding: ParameterEncoding = {
switch method {
case .get:
return URLEncoding.default
default:
return JSONEncoding.default
}
}()
return try encoding.encode(urlRequest, with: parameters)
}
Ответ №1:
После установки заголовка авторизации в вашем URLRequest
:
urlRequest.addValue("(APIConstants.API.token.rawValue) (token.key)", forHTTPHeaderField: "Authorization")
затем вы переопределяете все заголовки запроса, задав headers
свойство:
urlRequest.headers = headers
Хорошим решением было бы обновить headers
то, что вы уже создали выше, вот так:
var headers: HTTPHeaders = [
.contentType(APIConstants.ContentType.json.rawValue),
.accept(APIConstants.ContentType.json.rawValue),
]
if let token = token {
headers.add(.authorization("(APIConstants.API.token.rawValue) (token.key)"))
}
urlRequest.headers = headers
Комментарии:
1. Я обновил код в вопросе, чтобы лучше проиллюстрировать проблему, я жестко закодировал заголовок auth в массив с образцом токена, он все еще присутствует в сетевом мониторе
2. это была одна проблема, другая заключалась в том, что я пропустил трейлинг / который, казалось, повторял заголовок auth..go figure
Ответ №2:
Другим решением является использование пары ключевых значений следующим образом:
var header: HTTPHeaders = [:]
if let token = getValueFromUserDefaults(keyName: "authToken") as? String {
header["Authorization"] = token
}
Я всегда использую этот метод. Мне так удобнее.