0

I want to request a token via cURL using Swift Alamofire. However, I could not figure out so far how to pass on the right parameters in the right order to make it work.

The description given by Amadeus is the following:

enter image description here

 let headers = [
    "Content-Type": "application/x-www-form-urlencoded"
]

let params = [
    "grant_type": "client_credentials"
]


Alamofire.request("https://test.api.amadeus.com/v1/security/oauth2/token", method: .post, parameters: params, encoding: JSONEncoding.default, headers: headers).authenticate(user: "API", password: "API").responseJSON { response in debugPrint(response)

    let result = response.result.value
    print(result)
}

The expected result is to get JSON file in return including the token to make API requests. any help is highly appreciated. Thanks

Jakob
  • 195
  • 4
  • 12
  • Check this(https://stackoverflow.com/questions/53637437/alamofire-with-d/53637821#53637821) since you have a `cURL`. Also, does it work if you put the curl into a Terminal ? – Larme May 21 '19 at 22:07
  • The encoding `encoding: JSONEncoding.default` isn't JSON, so use `encoding: URLEncoding(destination: .httpBody)` – Larme May 22 '19 at 10:21

3 Answers3

1

Let's make use of usefull debug tools of Alamofire since you have a cURL sample.

Let's break your current code:

let headers = ["Content-Type": "application/x-www-form-urlencoded"]

let params = ["grant_type": "client_credentials"]

let request = Alamofire.request("https://test.api.amadeus.com/v1/security/oauth2/token",
                                method: .post,
                                parameters: params,
                                encoding: JSONEncoding.default,
                                headers: headers).authenticate(user: "API", password: "API")
print(request.debugDescription)
request.responseJSON { response in
    debugPrint(response)
    let result = response.result.value
    print(result)
}

Output:

$>curl -v \
-X POST \
-u API:API \
-H "Accept-Language: fr-US;q=1.0, en;q=0.9, fr-FR;q=0.8" \
-H "Accept-Encoding: gzip;q=1.0, compress;q=0.5" \
-H "User-Agent: iOSTest/1.0 (nt.iOSTest; build:1; iOS 12.2.0) Alamofire/4.8.1" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "{\"grant_type\":\"client_credentials\"}" \
"https://test.api.amadeus.com/v1/security/oauth2/token"

Let's go piece by piece: We should forget about Accept-Encoding, User-Agent & Accept-Language headers. I'll skip them later.

We see that the -d (data into httpBody) is wrong.

Let's change that: encoding: JSONEncoding.default to encoding: URLEncoding(destination: .httpBody). Plus it makes sense since in the content type we said it was url encoded.

We get then:

$>-d "grant_type=client_credentials"

Seems better.

We see the -u API:API \ which correspond to .authenticate(user: "API", password: "API"). We might want to remove it if the server doesn't manage authentification like that and put it into the params instead. So now, let's change the params:

let params = ["grant_type": "client_credentials",
              "client_id" : "APIKey",
              "client_secret" : "APISecret"]

We get:

$>-d "client_id=APIKey&client_secret=APISecret&grant_type=client_credentials" \

It should work then.

The order is not the same, but server shouldn't care about it. It should be a key/access not an index/access.

So final:

let headers = ["Content-Type": "application/x-www-form-urlencoded"]

let params = ["grant_type": "client_credentials",
              "client_id" : "APIKey",
              "client_secret" : "APISecret"]

let request = Alamofire.request("https://test.api.amadeus.com/v1/security/oauth2/token",
                                method: .post,
                                parameters: params,
                                encoding: URLEncoding(destination: .httpBody),
                                headers: headers)
print(request.debugDescription)
request.responseJSON { response in
    debugPrint(response)
    let result = response.result.value
    print(result)
}

Output (with skipped headers):

$ curl -v \
-X POST \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "client_id=APIKey&client_secret=APISecret&grant_type=client_credentials" \
"https://test.api.amadeus.com/v1/security/oauth2/token"
Larme
  • 24,190
  • 6
  • 51
  • 81
  • first of all: Your solution turned out to be exactly what I was looking for. Thanks for that. I edited your answer and added the API call. Unfortunately it returns unknown. Any suggestions why this might be the case? – Jakob May 22 '19 at 21:13
  • BTW security token stores the value from the .post method – Jakob May 22 '19 at 21:13
  • 1
    Don't try to edit my answers with another question. Instead create a new question. – Larme May 22 '19 at 21:53
  • Sorry. Created a new question – Jakob May 22 '19 at 22:13
0

The docs say that the parameters should include grant_type:client_credentials&client_id={client_id}&client_secret={client_secret}. Your parameters are missing the client ID and client secret. Make sure to include those by doing something like this:

let params = [
    "grant_type": "client_credentials&client_id=CLIENTIDHERE&client_secret=CLIENTSECRETHERE"
]
blorsch
  • 70
  • 1
  • 9
  • Thanks. Unfortunately amadeus server responds with error = "invalid_request"; "error_description" = "Only client_id, client_secret and grant_type parameters are allowed in the body"; title = "Invalid parameters"; – Jakob May 22 '19 at 06:56
0

The string that has to be passed as body is:

let params = [
    "grant_type=client_credentials&client_id=CLIENTIDHERE&client_secret=CLIENTSECRETHERE"
]

I don't know much about Swift but I guess you could do:

let params = [
    "grant_type": "client_credentials"
    "client_id" : "Your API Key"
    "client_secret" : "Your API Secret"
]
Anthony Roux
  • 1,421
  • 1
  • 8
  • 11