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

はじめに

弊社で開発している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を取得したり、アクセストークンを用いて投稿を取得したりすることができます。


『 Swift 』Article List
Category List

Eye Catch Image
Read More

Androidに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

AWSに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Bitcoinに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

CentOSに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

dockerに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

GitHubに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Goに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Javaに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

JavaScriptに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Laravelに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Pythonに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Rubyに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Scalaに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Swiftに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Unityに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Vue.jsに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Wordpressに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

機械学習に関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。