RailsでGithub OAuthからユーザー情報取得
Github API を用いてユーザーがアカウントへのアクセスを承認後 OAuth トークンを用いてユーザーのプロフィール情報を取得します。
流れとしては以下のようになります。
① Github アカウントへのアクセスへの承認を求める画面にユーザーが遷移する
② 承認後、指定したコールバック URL(Rails で設定する)に GET リクエストを送る。
③ GET リクエストのクエリパラメーターを用いてアクセストークンを取得
④ アクセストークンを用いて、ユーザーのプロフィール情報を取得
ルーティングにget 'callback', to: 'github_oauth#callback'
を追加します。
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
コールバック用のアクション追加
class Api::V1::GithubOauthController < ApplicationController
def callback
end
end
以下でアプリケーション登録します
https://github.com/settings/applications/new
HomepageURL はドメインを取得するまでは自分が持つ任意のドメイン。
CallbackURL は先ほど指定したコールバック URL になるようにする。
ドメインを取得したら適宜変える。
フロントエンドに以下のリンクを設置します。
clientId
には先ほど作成した Github アプリケーションの Client ID を入れてください。
クエリパラメーターのscope
には以下のリンクから選んでスコープを設定します。ユーザーが承認するときに何をリクエストしているか表示されます。
<a
href={`https://github.com/login/oauth/authorize?scope=read:user&client_id=${clientId}`}
>
Githubの内容を取得
</a>
ここからはコールバックしてきた時の挙動になります。
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 が入ります。
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)
アクション全体のコードは以下のようになります。
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