我想通过Alamofire 4.5发出HTTP帖子请求。该请求需要一个授权标头(这是一个Api密钥)。但每当我解雇请求时,我的服务器都无法检测到ApiKey
。
以下是我如何提出Alamofire请求
let params : [String : Any] =["param1":param1,"param2":param2]
let headers : HTTPHeaders = ["authorization" : apiKey]
Alamofire.request(MY_URL, method: .post, parameters: params, headers: headers).responseJSON {
response in
switch response.result{
case .success(let result):
//other code here
}
我三重检查apiKey
的值,值是正确的,但发送请求,我的服务器根本检测不到authorization
。
我完全不知道我在这里做错了什么,因为我在Swift中很新。请提供一个合适的解决方案。谢谢
编辑:
在我的服务器代码中,我使用Slim 2
$app->map('/MY_URL','authenticate',function ()use($app){
}
'authenticate'是在标题中扫描authorization: apiKey
的点,所以现在问题是我的服务器无法获得apiKey
的值因此总是给出相同的错误“Api Key is missing”,我没有找到Api Key时设置。
我在Alamofire Documentation尝试了下面的方法,但结果仍然相同。
我尝试了什么:
let headers: HTTPHeaders = [
"Authorization": "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==",
"Accept": "application/json"
]
Alamofire.request("https://httpbin.org/headers", headers: headers).responseJSON { response in
debugPrint(response)
}
我在这里想念的是什么?有人请给我一些提示来做这件事。谢谢。
编辑:
为了更清楚我的意思是authorization : apiKey
我展示了我在Postman
提出请求的方式。
通常我只是在请求中的标题中插入"authorization": apiKey
但在Swift中,Web服务无法获得apiKey
的值,因此服务器始终返回以下响应:
{
"error": true,
"message": "Api key is missing"
}
问题是iOS的URLRequest
会自动将标题大写。与此同时,API不遵循最佳实践。
更改您的API以符合RFC 7230
并允许它接受不区分大小写的标头。
起初,你的问题似乎有点奇怪,因为你提供的内容没有明显错误的代码。不过我试图在邮差中重现你的请求。
现在我们应该停下来,我必须警告你永远不要发布你在“这是我的请求”部分中所做的事情。这里给出的信息允许我在邮递员中完全重现您的请求(包括标题和确切字段的名称和值),这有助于解决您的问题。但与此同时,您可能会向所有看到您问题的人分享您的私人信息,甚至可能购买API密钥。这显然不好,如果可能,我建议您更改API密钥。
然后我尝试了你的代码并注意到你所说的完全相同的行为。我调试了responseJSON
闭包并观察了response.request?.allHTTPHeaderFields
属性:
(lldb) po response.request?.allHTTPHeaderFields
▿ Optional<Dictionary<String, String>>
▿ some : 2 elements
▿ 0 : 2 elements
- key : "Content-Type"
- value : "application/x-www-form-urlencoded; charset=utf-8"
▿ 1 : 2 elements
- key : "Authorization"
- value : "f8f99f9506d14f0590863d5883aaac9b"
(如果你不明白我写的内容,请阅读xcode中的调试,尤其是lldb
的po
命令)
正如您所看到的,授权标题的名称以大写A字母开头,即使我将它全部传递给小写字母。
我试图用邮政员用大写字母A发送新请求,是的 - 我了解到你的API只接受较低级别的授权标题名称。
“这不是一个真正的问题”你现在想的。 “我们应该在某处更改我们的授权标题名称,它应该没问题,对吧?”
不是那么容易。
我尝试了一些让我看到URLRequest的setValue(_:forHTTPHeaderField:)
方法的东西。 Alamofire称之为,我也尝试过。令人惊讶的是,在调用此方法后,“授权”标题始终更改为“授权”。然后我找到了对我们特别有趣的东西:
请注意,为了与HTTP RFC保持一致,HTTP头字段名称不区分大小写。
请记住,我甚至试图直接更改URLRequest的allHTTPHeaderFields
。得到了同样的结果。
这导致我们得出以下结论:Apple故意忽略输入标题的情况并且非常不负责任地更改它(再次故意,因为它在某处需要至少几行代码而不是直接将给定标题插入到请求中)。截至目前,我知道这个问题没有可能的解决方案(如果我们想把它归类为一个有点争议的问题)。搜索说这是从早期的iOS(http://0xced.blogspot.com.by/2010/06/fixing-nsmutableurlrequest.html)存在。您可以调用一些私有的Objective-c API,这可能有所帮助,但实际上您会遇到不稳定或未定义的行为,并且可能会被App Store拒绝。
所以我的结论,也许是在这种情况下唯一正确的选择是改变你的API。
Alamofire 4.6.0对我来说这很好用
let url = "WEB API URL"
let headers = [
"Content-Type":"application/x-www-form-urlencoded",
"authorization" : "apiKey"
]
let configuration = URLSessionConfiguration.default
configuration.requestCachePolicy = .reloadIgnoringLocalCacheData
let params : [String : Any] = ["param1":param1,"param2":param2]
Alamofire.request(url, method: .post, parameters: params as? Parameters, encoding: URLEncoding.httpBody, headers: headers).responseJSON { response in
if let JSON = response.result.value {
print("JSON: \(JSON)")
}else{
print("Request failed with error: ",response.result.error ?? "Description not available :(")
}
}
配置是可选的,您唯一需要的是设置请求权限。确保(双重确认)您正确格式化身份验证。
在某些情况下(不是罕见的情况,这应该格式如下:
["Authorization": "Bearer <#your_token#>"]
而我发现的Slim 2
它也与Bearer
所以也许你错过了这个。 https://github.com/dyorg/slim-token-authentication/tree/master/example#making-authentication-via-header
示例来自:
$ curl -i http://localhost/slim-token-authentication/example/restrict -H "Authorization: Bearer usertokensecret"
有了这个,你还可以检查这是否适用于简单的curl
命令。这应该。如果没有,你发送的字段肯定存在问题,而不是Alamofire本身。
在Alamofire的文档中,您可以找到:
/// Creates a `DataRequest` using the default `SessionManager` to retrieve the contents of the specified `url`,
/// `method`, `parameters`, `encoding` and `headers`.
///
/// - parameter url: The URL.
/// - parameter method: The HTTP method. `.get` by default.
/// - parameter parameters: The parameters. `nil` by default.
/// - parameter encoding: The parameter encoding. `URLEncoding.default` by default.
/// - parameter headers: The HTTP headers. `nil` by default.
///
/// - returns: The created `DataRequest`.
public func request(_ url: URLConvertible, method: Alamofire.HTTPMethod = default, parameters: Parameters? = default, encoding: ParameterEncoding = default, headers: HTTPHeaders? = default) -> Alamofire.DataRequest
这是一个例子:
Alamofire.request("https://...",
method: .get,
parameters: ["myKey1": "myValue1"],
encoding: JSONEncoding.default,
headers: self.authHeader).responseJSON { response in
//your response
}