post Image
[iOS]OAuth認証を極める(GitHubAPIで学ぶOAuth認証のフロー)

アプリでGitHubAPIを使用する

<対象>
・OAuth認証のフローを知りたい
・GitHubAPIをつかいたい

GitHubでは、検索やリポジトリの読み書き、プルリクエストの生成・更新・削除などいろいろなAPIが提供されています。
GitHubAPI

これらは
アクセストークンなしでAPIを使用することもできるのですが、その場合はAPIでできることが一部制限されてしまいます。例えば、SearchAPIには以下のような注釈があります。

Note: You must authenticate to search for code across all public repositories.
パブリックなリポジトリを対象に検索を実行するには認証が必要です

というわけで、APIの全機能を使うためにはGitHub認証が必要になるわけです。

本記事ではiOSアプリでGitHub認証しアクセストークンを取得するまで(OAuth認証の流れとアプリ側の実装)をまとめました!

OAuth認証のフロー

・事前準備
ここからGitHubのアプリを新規に作成します。
必要事項を記入し、完了するとClient IDClient Secretが発行されます。

でここからがアプリ内での処理です。

① 認可リクエスト
GithubのAPIを使ったアプリのサービスを受けたいので、「認可リクエスト」を行う
→ WebViewなどで認証画面を表示する
→ ユーザーはGithubにログインし、アプリに代理アクセスすることを許可する(連携認証の許可)
→ GitHubからコールバック
→ GitHubから認証コードをレスポンスとしてもらう

② アクセストークン取得
もらったコードを使ってアプリはGithubの「アクセストークン交換場所 (Token Endpoint)」にアクセスします。
その際、認証コードを「アクセストークン」に変換する為に、アプリは事前の登録で取得したクレデンシャル(Client IDClient Secret)で認証を受けます。 (クライアント認証)
正しく認証されると、コードと引き換えにアクセストークンをもらいます。

以上の流れは「コードフロー」と呼ばれ、基本的なOAuthのフローです。

図にすると以下のような感じです。
スクリーンショット 2018-05-05 4.31.04.png

アプリで実装してみる

流れがわかったので、実装に落とし込んでみます。

(以下ではライブラリとして、Alamofire, Swiftyjsonを利用しています)

① 認可リクエスト


let gitOuthUrl = URL(string: "https://github.com/login/oauth/authorize?client_id={ 
取得したクライアントID }&scope=public_repo")
let gitOuthRequest = URLRequest(url: gitOuthUrl!)
webView.load(gitOuthRequest)

上記ではwebViewで認可リクエストを送っています。
scope=public_repoはパブリックなリポジトリに対する読み書き権限を要求していることを示します。なくてもOKです。参考
で、以下のように連携認証のためにログインが求められます。

Simulator Screen Shot - iPhone X - 2018-05-06 at 00.04.24.png

ここでログインを実行するとコールバックURLが実行され、認証コードを取得できるので、それを取得する処理を書きます。


func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) { 

        // 設定しているコールバックURLのスキーム、ホスト名で分岐処理       
        if navigationAction.request.url?.scheme == "yyokii", navigationAction.request.url?.host == "GithubSearchApp"{
            dismiss(animated: true, completion: nil)

            // 認証コード取得
            let code = getQueryStringParameter(url: (navigationAction.request.url?.absoluteString)!, param: "code")


            // ② アクセストークン取得処理
            let githubAPIManager = GithubAPIManager.sharedManager
            githubAPIManager.getAccessToken(code: code, completion: nil)

            decisionHandler(WKNavigationActionPolicy.allow);
}


static func getQueryStringParameter(url: String, param: String) -> String? {
        guard let url = URLComponents(string: url) else { return nil }
        return url.queryItems?.first(where: { $0.name == param })?.value
    }

ここで使用されるコールバックURLはGithHubでアプリ登録したときに設定したURLとなります。
コールバックURLが叩かれたときにクエリパラメーターに付与されている認証コードを取得しています。

② アクセストークン取得処理


    /// アクセストークンを取得
    ///
    /// - Parameter code: このコードとアクセストークンを交換
    func getAccessToken(code: String!, completion: @escaping () -> Void) {
        self.code = code
        let url = "https://github.com/login/oauth/access_token"

        // 受信可能なレスポンスデータのメディアタイプを指定
        let headers = [
            "ACCEPT": "application/json"
        ]

        // 認証に必要な値を設定
        let parameters: Parameters = [
            "client_id": self.clientId,
            "client_secret": self.clientSecret,
            "code": self.code
            ]

        Alamofire.request(url, method: .post, parameters: parameters, encoding: URLEncoding.default, headers: headers).responseJSON{ response in

            switch response.result {
            case .success:
                let json = JSON(response.result.value!)

                // アクセストークンを取得
                let accessToken = json["access_token"].string
                UserDefaults.standard.set(accessToken!, forKey: ACCESS_TOKEN)
                completion()
            case .failure(let error):
                print(error)
            }
        }
    }

ヘッダー、リクエストパラメーターを設定し、"https://github.com/login/oauth/access_token"をPOST通信で叩きます。でそのレスポンスからアクセストークンを取得しています。

このアクセストークンを使用してAPIを叩くには、ヘッダーに
"Authorization": "token " + {取得したアクセストークン}をつければOKです!!

おわり!!!


『 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

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