Search code examples
iosoauthinstagraminstagram-api

Instagram Oauth Redirect on iOS


I'm writing an iOS Application that needs to use Oauth to connect to Instagram. The standard iOS mechanism for o-auth is to provide a redirect URL with a custom scheme. For instance, myapp://oauth/redirect -- And register that in your iOS app. Which is all fine and dandy, except the management portal for Instagram seems to prevent any scheme but http or https when you setup your valid redirect URI's.

Example

Any thoughts on how to make this work? Am I forced to add a server component to capture / redirect?


Solution

  • There are two approaches to doing this without using a custom URL Scheme, each with positives and negatives:

    1. Universal Links - PROS: Redirects to Safari so you don't have to build in a web browser yourself. Safari redirect also allows for using the users iCloud keychain which can make the login experience easier for your user. CONS: Setting it up is kind of a bear, and requires your own server and a published app. Doesn't seem to work in simulator.
    2. Setup and present a UIWebView, and in webView:shouldStartLoadWithRequest:navigationType: catch the access token from the fragment, and prevent loading / redirection. This allows you to use any URL you want as the redirect URL because it doesn't matter :)

    Example:

    import UIKit
    
    class OAuthVC : UIViewController, UIWebViewDelegate {
        @IBOutlet var webView : UIWebView?
    
        public var success : ((URLRequest) -> Void)?
        public var presentVC : UIViewController?
    
        func handle(_ url: URL) {
            view.tag = 1 // Make sure our view and thus webview is loaded.
            webView!.loadRequest(URLRequest(url: url))
        }
    
        func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool {
            if request.url?.fragment?.contains("access_token") == true {
                success!(request)
                dismiss(animated: true, completion: nil)
                return false
            }
            return true
        }
    
        func webViewDidFinishLoad(_ webView: UIWebView) {
            // If we stop on a page before the redirect closes us, user interaction is required.  Present.
            presentVC?.present(self, animated: true, completion: nil)
        }
    }
    

    List item