top_logo

RailsでGithub OAuthからユーザー情報取得

2022年 08月 21日

Github API を用いてユーザーがアカウントへのアクセスを承認後 OAuth トークンを用いてユーザーのプロフィール情報を取得します。


流れとしては以下のようになります。


① Github アカウントへのアクセスへの承認を求める画面にユーザーが遷移する


② 承認後、指定したコールバック URL(Rails で設定する)に GET リクエストを送る。


③ GET リクエストのクエリパラメーターを用いてアクセストークンを取得


④ アクセストークンを用いて、ユーザーのプロフィール情報を取得


参考

GitHub Docs



コールバックの URL とアクション追加


ルーティングにget 'callback', to: 'github_oauth#callback' を追加します。


config/routes.rb
Rails.application.routes.draw do
  root to: 'home#index'
  namespace :api, format: 'json'  do
    namespace :v1 do
			# 追加
      get 'callback', to: 'github_oauth#callback'
    end
  end
end

コールバック用のアクション追加

app/controllers/api/v1/github_oauth_controller.rb
class Api::V1::GithubOauthController < ApplicationController
  def callback

  end
end

Github にアプリケーションに登録

以下でアプリケーション登録します


https://github.com/settings/applications/new


HomepageURL はドメインを取得するまでは自分が持つ任意のドメイン。


CallbackURL は先ほど指定したコールバック URL になるようにする。


ドメインを取得したら適宜変える。


スクリーンショット 2022-08-17 14 08 18

フロントエンドにリンク設置

フロントエンドに以下のリンクを設置します。


clientIdには先ほど作成した Github アプリケーションの Client ID を入れてください。


クエリパラメーターのscopeには以下のリンクから選んでスコープを設定します。ユーザーが承認するときに何をリクエストしているか表示されます。


https://docs.github.com/ja/developers/apps/building-oauth-apps/scopes-for-oauth-apps#requested-scopes-and-granted-scopes


<a
  href={`https://github.com/login/oauth/authorize?scope=read:user&client_id=${clientId}`}
>
  Githubの内容を取得
</a>

スクリーンショット 2022-08-21 22 58 48

ユーザー情報の取得に必要なトークンをリクエスト

ここからはコールバックしてきた時の挙動になります。


Faraday を用いてアクセストークンを取得します。


ENV['GITHUB_FETCH_TOKEN_URL']には https://github.com/login/oauth/access_tokenが入ります


ENV['REACT_APP_CLIENT_ID']には Github アプリケーションの Client ID が入ります。


ENV['CLIENT_SECRET']には Github アプリケーションの Client Secret が入ります。


app/controllers/api/v1/github_oauth_controller.rb
Faraday.default_adapter = :net_http

class Api::V1::GithubOauthController < ApplicationController
  def callback
    conn = Faraday.new do |builder|
      builder.request :json
    end
    response = conn.post(ENV['GITHUB_FETCH_TOKEN_URL'], { client_id: ENV['REACT_APP_CLIENT_ID']
    # 改行してますが繋げてください
    , client_secret: ENV['CLIENT_SECRET'], code: params[:code] })

    access_token = Rack::Utils.parse_nested_query(response.body)['access_token']

  end
end

params[:code]はコールバック時のクエリパラメーターです。このコードとアクセストークンを引き換えるようです。


ユーザー情報を取得

アクセストークンを用いて以下のコードでユーザー情報をリクエストしてユーザーの GitHub プロフィール情報を取得します。


ENV['GITHUB_API_URL']には https://api.github.comが入ります


req = Faraday.new(
  url: "#{ENV['GITHUB_API_URL']}/user",
  headers: { "Authorization": "token #{access_token}" }
)
user_response = req.get
user_info = JSON.parse(user_response.body)

アクション全体のコードは以下のようになります。

app/controllers/api/v1/github_oauth_controller.rb
Faraday.default_adapter = :net_http

class Api::V1::GithubOauthController < ApplicationController
  def callback
    conn = Faraday.new do |builder|
      builder.request :json
    end
    response = conn.post(ENV['GITHUB_FETCH_TOKEN_URL'],
    # 改行してますが繋げてください
    { client_id: ENV['REACT_APP_CLIENT_ID'], client_secret: ENV['CLIENT_SECRET'], code: params[:code] })
    access_token = Rack::Utils.parse_nested_query(response.body)['access_token']

    req = Faraday.new(
      url: "#{ENV['GITHUB_API_URL']}/user",
      headers: { "Authorization": "token #{access_token}" }
    )
    user_response = req.get
    user_info = JSON.parse(user_response.body)
  end
end

これでユーザーの情報が取得できました。


最後まで見ていただきありがとうございました。


分かりにくい、または間違っているところあれば連絡いただければと思います。

連絡先

何か連絡をしたい際は以下 SNS、メールでお願いいたします。

Twitter:  https://twitter.com/naka_ryo_z

Github:  https://github.com/ryotaro-tenya0727

メール:   ryotaro123110@gmail.com

見出しへのリンク

© 2024, written by Nakayama

Powered by Gatsby