简体   繁体   English

如何在Alamofire 4.5,Swift 4中的标头中发送`apikey`?

[英]How to send `apikey` in header in Alamofire 4.5,Swift 4?

I want to make a HTTP post request via Alamofire 4.5. 我想通过Alamofire 4.5发出HTTP发布请求。 The request need an authorization header(which is a Api key). 该请求需要一个授权标头(这是一个Api密钥)。 But whenever I fired the request,my server cant detect the ApiKey .' 但是,每当我发出请求时,我的服务器就无法检测到ApiKey

Here is how I make the Alamofire request 这是我发出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
}

I triple checked the value of apiKey ,the value is correct,but the request sent,my server cant detect the authorization at all. 我三重检查了apiKey的值,该值正确,但是发送了请求,我的服务器根本无法检测到authorization

I totally no idea whether I do anything wrong here,cause I very new in Swift.Kindly provide a proper solution.Thanks 我完全不知道我在这里是否做错什么,因为我是Swift的新手。请提供适当的解决方案。谢谢

Edit : 编辑:

In my server code,I using Slim 2 在我的服务器代码中,我使用Slim 2

$app->map('/MY_URL','authenticate',function ()use($app){

}

'authenticate' is the point that scan for the authorization: apiKey in the headers,so now the problem is my server cant get the value of apiKey therefore always giving the same error "Api Key is missing" which I set when no Api Key found. “ authenticate”是扫描authorization: apiKey的关键点authorization: apiKey标头中的authorization: apiKey ,所以现在的问题是我的服务器无法获取apiKey的值,因此始终给出相同的错误“ Api Key is missing”,该错误在找不到Api Key时设置。

I tried the method below in Alamofire Documentation ,but the result still the same. 我尝试了以下Alamofire文档中的方法,但结果仍然相同。

What I tried: 我试过的

 let headers: HTTPHeaders = [
    "Authorization": "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==",
    "Accept": "application/json"
]

Alamofire.request("https://httpbin.org/headers", headers: headers).responseJSON { response in
    debugPrint(response)
}

What I missing here?Somebody please give me some hints to do it..Thank you. 我在这里缺少什么?有人可以给我一些提示。谢谢。

EDIT: 编辑:

To be more clear on my I mean for authorization : apiKey I show the way I make request in Postman . 为了更清楚地说明我的意思是authorization : apiKey我展示了我在Postman发出请求的方式。

Normally I just insert the "authorization": apiKey in the Headers in the request 通常我只在请求的Headers中插入"authorization": apiKey

在此处输入图片说明

but in Swift,the web service cant get the value of apiKey ,therefore the server always return this following response : 但是在Swift中,Web服务无法获取apiKey的值,因此服务器始终返回以下响应:

{
  "error": true,
  "message": "Api key is missing"
}

This is working fine for me with Alamofire 4.6.0 使用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 :(")

        }
    }

Configuration is optional, the only thing you need is to setup request right. 配置是可选的,您唯一需要做的就是正确设置请求。 Make sure ( double sure ) that you format your auth correctly. 确保( 双重确认 )您正确设置了身份验证的格式。

In some (not that rare cases this should be formatted like this: 在某些情况下(并非罕见),应采用以下格式:

["Authorization": "Bearer <#your_token#>"]

And what I found about Slim 2 it's also with Bearer so maybe you missing this. 我对Slim 2的发现也与Bearer所以也许您错过了它。 https://github.com/dyorg/slim-token-authentication/tree/master/example#making-authentication-via-header https://github.com/dyorg/slim-token-authentication/tree/master/example#making-authentication-via-header

Example from this: 来自此的示例:

$ curl -i http://localhost/slim-token-authentication/example/restrict -H "Authorization: Bearer usertokensecret"

With this, you can also check if this working with simple curl command. 使用此命令,您还可以使用简单的curl命令检查此命令是否有效。 It should. 这应该。 If not, there is definitely a problem with fields you're sending rather than Alamofire itself. 如果没有,肯定是您要发送的字段存在问题,而不是Alamofire本身存在问题。

In docs for Alamofire you can find: 在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

Here is an example: 这是一个例子:

Alamofire.request("https://...",
                   method: .get,
                   parameters: ["myKey1": "myValue1"], 
                   encoding: JSONEncoding.default,
                   headers: self.authHeader).responseJSON { response in 
                        //your response
                   }

TLDR; TLDR;

The problem is that iOS's URLRequest automatically capitalize headers. 问题是iOS的URLRequest自动将标题大写。 At the same time you API does not follow best practices. 同时,您的API并未遵循最佳做法。

Change your API to comply to RFC 7230 and allow it to accept headers case-insensitively . 更改您的API以符合RFC 7230并允许它不区分大小写地接受标头。

The whole story: 整个故事:

At first, your question seemed a bit odd since there is no obviously wrong code in what you provided. 起初,您的问题似乎有点奇怪,因为您提供的内容中显然没有错误的代码。 Nevertheless I tried to reproduce your request in Postman. 不过,我尝试在邮递员中重现您的请求。

Now we should stop and I must warn you to never post what you did in your "Here is my request" section. 现在我们应该停止,我必须警告您不要在“这里是我的请求”部分中发布您所做的事情。 The information given there allowed me to completely reproduce your request in Postman (including headers and exact fields' names and values), which is good to solve your problem. 那里提供的信息使我可以在Postman中完全重现您的请求(包括标题和确切字段的名称和值),这对于解决您的问题很有帮助。 But at the same time you shared your presumably private and maybe even bought API key to everyone who see your question. 但与此同时,您也将自己的个人信息共享给了所有人,甚至还向看到您问题的所有人购买了API密钥。 Which is obviously not good and I would recommend you to change your API key if it is possible. 显然这不好,我建议您尽可能更改您的API密钥。

Then I tried your code and noticed exactly the same behavior you talking about. 然后,我尝试了您的代码,发现与您所说的行为完全相同。 I debugged responseJSON closure and observed response.request?.allHTTPHeaderFields property: 我调试了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"

(if you don't understand what I wrote read about debugging in xcode and in particular for lldb 's po command) (如果您不理解我所写的内容,则是有关使用xcode调试的内容,尤其是有关lldbpo命令的内容)

As you can see, authorization header's name start with a capital A letter even though I passed it all lowercased. 如您所见,授权标头的名称以大写字母A开头,即使我将其全部用小写字母传递也是如此。

I tried to send new request with postman with capital A and yes - I learned that your API accepts only lower-cased authorization header name. 我尝试用大写A向邮递员发送新请求,是的-我了解到您的API仅接受小写的授权标头名称。

"It isn't really a problem" you think right now. 您现在想:“这不是真正的问题。” "We should just change our authorization header name somewhere and it should be just fine, right?" “我们应该只在某个地方更改授权标头名称,就可以了,对吧?”

NOT SO EASY. 不太容易。

I tried a few things which all lead me to the URLRequest's setValue(_:forHTTPHeaderField:) method. 我尝试了一些使我都进入URLRequest的setValue(_:forHTTPHeaderField:)方法的setValue(_:forHTTPHeaderField:) Alamofire calls it and I tried it too. Alamofire称之为,我也尝试过。 Surprisingly enough after calling this method "authorization" header always changes to "Authorization". 令人惊讶的是,调用此方法后,“授权”标头始终更改为“授权”。 Then I found the thing that particularly interesting for us: 然后我发现这件事对我们特别有趣:

Note that, in keeping with the HTTP RFC, HTTP header field names are case-insensitive. 请注意,为了与HTTP RFC保持一致,HTTP标头字段名称不区分大小写。

Keep in mind that I even tried to change URLRequest's allHTTPHeaderFields directly. 请记住,我什至尝试直接更改URLRequest的allHTTPHeaderFields Had the same result. 有同样的结果。

Which leads us to the following conclusion: Apple intentionally ignores input headers' case and very irresponsibly changes it (again intentionally since it takes at least a few lines of code somewhere instead of just plugging given headers directly into request). 这导致我们得出以下结论:Apple故意忽略了输入标头的大小写,并且非常不负责任地对其进行了更改(再次故意这样做,因为它在某处至少需要几行代码,而不仅仅是将给定的标头直接插入请求中)。 As of now I know no possible solution to this problem (if we want to classify it as a problem which is a bit controversial). 到目前为止,我还没有解决该问题的方法(如果我们想将其归类为有点争议的问题)。 Search says that is exists from earlier days of iOS ( http://0xced.blogspot.com.by/2010/06/fixing-nsmutableurlrequest.html ). 搜索表明存在于iOS的早期版本中( http://0xced.blogspot.com.by/2010/06/fixing-nsmutableurlrequest.html )。 You could call some private objective-c APIs which could help, but in fact you'll get unstable or undefined behavior and would likely get rejected from App Store. 可以调用一些私有的Objective-C API,这可能会有所帮助,但实际上,您将获得不稳定或不确定的行为,并有可能被App Store拒绝。

So my conclusion, and probably the only right choice in this situation is to change your API. 所以我的结论,在这种情况下,也许唯一正确的选择是更改您的API。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在 Alamofire Swift iOS 中将 Origin 传递给 Header? - How to pass Origin to Header in Alamofire Swift iOS? 如何使用Alamofire和Mailgun使用Swift发送电子邮件? - How to send email using Alamofire and Mailgun with Swift? 如何在 Swift 中将数组作为参数发送到 Alamofire - how to send array to Alamofire as a Paremeter in Swift Alamofire / Swift-如何在请求中添加布尔标头值 - Alamofire/Swift - How to add a boolean header value in request 如何在 Swift 中使用 Alamofire 在 http 标头中将整数值作为参数传递? - How to pass integer value as a parameter in http header using Alamofire in Swift? Alamofire 2.0和Swift 2-标头不起作用。 看看如何解决 - Alamofire 2.0 and Swift 2 - Header is not working. See how to fix it 快速发送带有参数的 Alamofire 请求 - Send Alamofire request with parameters in swift 如何快速发送令牌字符串(jwt)作为Alamofire Post请求中的Cookie? - How to send token string (jwt) as Cookie in Alamofire Post request in swift? 带有签名请求的Swift Alamofire文件上传:如何发送授权标头? - Swift Alamofire file upload with signed request: how to send authorization headers? 如何使用swift中的POST方法使用参数和标头在Alamofire中发送请求 - How to send request in Alamofire with parameters and headers using POST method in swift
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM