LoginSignup
39
22

More than 5 years have passed since last update.

Instagram APIでOAuth認証する (Swift3版)

Last updated at Posted at 2017-08-01

はじめに

弊社で開発しているiOSアプリTABLESでは、Instagramに登録されているユーザ情報を用いてログインする機能を実装しました。Instagramに登録されているユーザ情報を取得するためには、Instagram APIを用いる必要がありましたが、InstagramはAPIを使うためのiOS用のSDKが配布されていなかったため、WebViewを用いて地道に実装しました。

InstagramのユーザID取得の流れ

以下の手順に沿ってInstagramのユーザIDを取得します
1. Authorization APIで認可コードを発行する
2. ユーザが承認した場合、リダイレクト先に認可コードが返ってくる
3. 認可コードをもとに、ユーザ情報を取得するAPIを叩く
4. ユーザ情報のJSONからユーザIDを取得する

ユーザIDを取得するためには2の認可コードを必ず取得する必要があります。TABLESでは3と4はサーバ側で行ったので、今回は2の認可コードを取得することをゴールとしています。

Authorization APIで認可コードを発行する

まずはInstagramから認可コードを発行するためのAuthorization APIを叩きます。下記がURLになります

"https://api.instagram.com/oauth/authorize/?client_id=CLIENT-ID&redirect_uri=REDIRECT-URI&response_type=code"

これをWebViewに表示します。今回はUIWebviewではなくWKWebviewを使いました。
WKWebviewは、最初に表示するURLを指定して表示することができるので、以下のようにAuthorization APIを指定して表示します。

ViewController.swift
override func viewDidLoad() {
    super.viewDidLoad()

    let instagramAuthUrl = "https://api.instagram.com/oauth/authorize/?client_id=CLIENT-ID&redirect_uri=REDIRECT-URI&response_type=code"

    let instagramWebView = WKWebView()
    let requestURL = NSURL(string: instagramAuthUrl)
    let request = NSURLRequest(url: requestURL! as URL)

    instagramWebView.load(request as URLRequest)
    instagramWebView.navigationDelegate = self
    view = instagramWebView
}

すると以下のような画面がWebViewに表示されます。

43df965e-20e0-a78d-d8de-c3f3829ed9ed.png

認可コードを取得する

次に認可コードを取得します。上の画面でユーザネームとパスワードを入力すると以下のようなページに遷移します。

ceff3b41-92c1-6e92-4a2b-3fb0facd686c.png

ここでユーザがAuthorizeをタップすると、以下のように認可コードがリダイレクト先にパラメータとして送られます。
REDIRECT-URI?code=CODE

よって認可コードを取得するためにはWebViewで以下を実装する必要があります。

  1. 表示されているページのURIが登録したリダイレクトURIかどうかを判断する
  2. URIをパースして認可コードを取得する

以上の機能を実装したソースコードが次のようになります。

ViewController.swift

func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
    let redirectURL = "[API利用申請時に登録したリダイレクトURL]"
    let URL = navigationAction.request.url.absoluteString!

    if Regexp(redirectURL).isMatch(URL ?? "") {
        let comp = NSURLComponents(string: URL)
        let code = comp?.queryItems?[0].value
        // codeが取れているか確認する
        print("---code---")
        print(code ?? "")
    }
}

正規表現用のクラスは以下になります。

Regexp.swift
import Foundation

class Regexp {

    let regexp: NSRegularExpression
    let pattern: String

    init(_ pattern: String) {
        self.pattern = pattern

        do {
            self.regexp = try NSRegularExpression(pattern: pattern, options: NSRegularExpression.Options.caseInsensitive)
        } catch let error as NSError {
            print(error)
            self.regexp = NSRegularExpression()
        }
    }

    func isMatch(_ input: String) -> Bool {
        let matches = internalRegexp.matches( in: input, options: [], range:NSMakeRange(0, input.characters.count) )
        return matches.count > 0
    }

}

1.表示されているページのURIが登録したリダイレクトURIかどうかを判断する

WKWebviewのdecidePolicyFor navigationActionというデリゲートメソッドは、アクセスするURLが変更されるタイミングで呼ばれます。navigationAction.request.urlでリダイレクト先のURIがとれるので、リダイレクト先のURIが登録したURIかどうかを正規表現で判断しました。

2.URIをパースして認可コードを取得する

URIのパースは、NSURLComponentsというオブジェクトによって実装しました。NSURLComponents.queryItemsとするとクエリパラメータが取得できます。

実行結果

---code---
3f63e1d6b0356d00976ee5e7d4158ae1

認可コードがとれました(上記の認可コードは適当な文字列です)。認可コードを使えば、ユーザIDを取得したり、アクセストークンを用いて投稿を取得したりすることができます。

39
22
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
39
22