5

Hi I am having an issue with Instagram while performing authentication process. It was working fine few weeks ago, nothing changed in the code.

The issue now facing is that after a login process of Instagram, safari display an error "Bad request 400" and nothing more then that.

Avi
  • 7,469
  • 2
  • 21
  • 22
Usman Nisar
  • 3,031
  • 33
  • 41

3 Answers3

4

Recently I had the same problem with the Instagram api. Everything was working fine and suddenly 400 bad request - You must provide a client_id.

I debugged the OAuth 2.0 flow and after extensive research realized that I should set a

Content-Type:application/x-www-form-urlencoded

header in the request. So if someone else has this problem make sure you have the header set in the request that retrieves the access token.

iliyan tanev
  • 377
  • 2
  • 15
1

I used WKWEbView because of redirect uri

func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
        //print(webView.url?.absoluteString)
        decisionHandler(.allow)

        let searchString = "https://example.com"//your redirect uri


        if (webView.url?.absoluteString.starts(with: searchString))! {
            let code = extractCode(webView.url!.absoluteString)
              if code != nil{
                print("*****found")
                  print("code: \(code)")
                  self.loginWithInstagram(code!)
              }
          }
    }


    func loginWithInstagram(_ code: String) {

        let headers = [
          "Content-Type": "application/x-www-form-urlencoded",
          "Accept": "*/*",
          "Cache-Control": "no-cache",
          "Host": "api.instagram.com",
          "Accept-Encoding": "gzip, deflate",
          "Content-Length": "237",
          "Connection": "keep-alive",
          "cache-control": "no-cache"
        ]

        let postData = NSMutableData(data: "client_id=xxx".data(using: String.Encoding.utf8)!)
        postData.append("&code=".data(using: String.Encoding.utf8)!)
        postData.append(code.data(using: String.Encoding.utf8)!)
        postData.append("&redirect_uri=https://example.com".data(using: String.Encoding.utf8)!)
        postData.append("&grant_type=authorization_code".data(using: String.Encoding.utf8)!)
        postData.append("&client_secret=xxx".data(using: String.Encoding.utf8)!)

        let request = NSMutableURLRequest(url: NSURL(string: "https://api.instagram.com/oauth/access_token")! as URL,
                                                cachePolicy: .useProtocolCachePolicy,
                                            timeoutInterval: 10.0)
        request.httpMethod = "POST"
        request.allHTTPHeaderFields = headers
        request.httpBody = postData as Data

        let session = URLSession.shared
        let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in


            guard let unwrappedData = data else { return }
            do {
                let str = try JSONSerialization.jsonObject(with: unwrappedData, options: .allowFragments)

                print(str)

            } catch {
                print("json error: \(error)")
            }

          if (error != nil) {
            //print(error)
          } else {
            let httpResponse = response as? HTTPURLResponse
            //print(httpResponse)
          }
        })

        dataTask.resume()
    }
}

// This works on my app

Alp Altunel
  • 3,324
  • 1
  • 26
  • 27
codaman
  • 206
  • 4
  • 6
0

The problem you're seeing is related to the callback URL. Instagram no longer seems to accept custom schemes. Your callback needs to be http or https ( it can't be, for example customapp:// ).

Alex
  • 712
  • 1
  • 5
  • 11
  • How would you do authentication on an iOS app then? – shakked Jun 29 '16 at 04:16
  • You need to do in a web view ( UI or WK ). Intercept the relevant delegate methods. In the case of UIWebView, check for your callback URL when the delegate is asked if it should load a URL. If it's your callback URL, return NO to stop the loading, parse the token out of the URL and you're on your way. – Alex Jun 29 '16 at 04:20