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
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.
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
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:// ).