I am developing an iOS app (using Swift) that allows the user to authenticate through Instagram using OAuth 2.0
In the past, everything was working fine as I was able to specify the authorization URL as such:
https://api.instagram.com/oauth/authorize/?client_id=xxx&redirect_uri=myiosapp://authorize&response_type=code
The key point here being the redirect_uri myiosapp://authorize
My problem is that I am no longer able to register a custom url scheme with Instagram thereby making it impossible(?) to handle the redirect exclusively through my app. If I do try to add such a URI in the "Valid redirect URIs:" field, I get the following error:
You must enter an absolute URI that starts with http:// or https://
What is the recommended way to handle authentication with Instagram exclusively thrugh an iOS native application?
After figuring it out, I thought I'd post my solution for anyone who comes across the same problem.
First of all, I'll just accept that Instagram no longer allows custom schemas in the "Security" -> "Valid redirect URIs" field. Instead, I will enter an arbitrary but valid URI that I can uniquely identify. For example: http://www.mywebsite.com/instagram_auth_ios
Now, when attempting to authorize with Instagram, I'll use that as the redirect URI - even though no webpage actually exists at that URI.
Example: https://api.instagram.com/oauth/authorize/?client_id=xxx&redirect_uri=http://www.mywebsite.com/instagram_auth_ios&response_type=code
Finally, I'll use the UIWebViewDelegate
's shouldStartLoadWithRequest
method to intercept the redirect request before it runs, and instead call my original custom uri (that way I don't have to rewrite anything). Here's how I wrote that method:
func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
guard let url = request.URL where url.host == "www.mywebsite.com" && url.path == "/instagram_auth_ios" else { return true }
guard let authUrl = NSURLComponents(URL: url, resolvingAgainstBaseURL: false) else { return true }
// Customize the scheme/host/path, etc. as desired for your app
authUrl.scheme = "myappschema"
authUrl.host = "instagram"
authUrl.path = ""
UIApplication.sharedApplication().openURL(authUrl.URL!)
return false
}
There's one small caveat with returning false in the shouldStartLoadWithRequest method in that it will always complain with a "Frame Load Interrupted" error. This doesn't seem to adversely affect anything and can (probably) be safely ignored.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With