Search code examples
swiftapioauthnsmutableurlrequestimgur

Swift 3 Oauth2 Imgur Refresh keys - error 400 "Invalid grant_type parameter or parameter missing"



I have an issue when calling the /oauth2/token endpoint of the Imgur API using Swift / NSMutableURLRequest and maybe it's actually just me setting up the request in a wrong way as I don't have a lot of experience with NSMutableURLRequest.
Scenario:
The user has already authenticated my App, he can post photos to his Imgur account.

Problem:
Imgur requires to re-authenticate after 28 days.
That's why after authenticating the App you get a (temporary; for 28 days) access_token and a long-term refresh_token which you use after 28 days to get a new access_token.
I do following API call to retrieve a new access_token but always get the error:
"Invalid grant_type parameter or parameter missing" with error code 400.
Here is my HTTP request:

if let reqUrl = URL(string: "https://api.imgur.com/oauth2/token?refresh_token=\(refreshKey)&client_id=\(CLIENT_ID)&client_secret=\(IMGUR_SECRET)&grant_type=refresh_token")
    {
        let request = NSMutableURLRequest(url: reqUrl)
        print("request: \(reqUrl)")
        request.httpMethod = "POST"
        request.setValue("Client-ID \(CLIENT_ID)", forHTTPHeaderField: "Authorization")
        request.addValue("application/x-www-form-urlencoded; charset=utf-8", forHTTPHeaderField: "Content-Type")

        let task = URLSession.shared.dataTask(with: request as URLRequest){ data, response, error in
            if (error != nil){
                print("error: \(error)")
                return
            }
            print("response: \(response!)")
            let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
            print("response string: \(responseString!)")
        }
        task.resume()
    }

refreshKey, CLIENT_ID and IMGUR_SECRET should all be correct.

Thank you in advance for your help!


Solution

  • So, I solved it this way:

    let bodyString = "grant_type=refresh_token&client_secret=\(IMGUR_SECRET)&client_id=\(CLIENT_ID)&refresh_token=\(refreshKey)"
    
    request.httpBody = bodyString.data(using: .utf8)
    

    basically setting the parameters in the request's body instead of putting them in the URL. Hope this can help someone else, too :)