github 認証や google 認証など、アプリケーションへ既存の所有アカウントを利用してのログインを提供する機能に OAuth 認証があります。
今回は github 認証の実装を確認し、独自のプロバイダとそこへのクライアントを作成してみます。
目次
参考
- github - omniauth/omniauth
- github - omniauth/omniauth-github
- Qiita - doorkeeper を使って omniauth の provider&client 作成を懇切丁寧にまとめた
github 認証するクライアントを作る
devise を導入したユーザー認証する環境を用意
毎度、User モデルを認証する環境を作っているので、割愛。
Ruby on Rails での認証(Devise ライブラリ)を参照してもらえるといい。
Client id と Client secret を入手
github にログインし、設定を開き「Developer settings」に進みます。
「Register a new application」からアプリケーションを登録します。
必要情報を登録します。
作成できた Client id と Client secret を控えておきます。
omniauth を導入する
それでは、github 認証を行うにあたって必要な gem omniauth を導入してみる。
以下を Gemfile に追記する。
1 | gem 'omniauth' |
config/initializers/devise.rb
を編集してプロバイダに github を登録します。
1 | Devise.setup do |config| |
User モデルに、omniauth 用のカラムを追加します。
以下の内容でマイグレーションをします。
1 | class AddColumnsToUsers < ActiveRecord::Migration[5.2] |
app/models/user.rb
を以下のように編集します。
1 | class User < ApplicationRecord |
続いて github 認証後に実行されるコールバック処理を作成します。app/controllers/omniauth_collbacks_contoroller.rb
を以下の通り作成します。
1 | class OmniauthCallbacksController < Devise::OmniauthCallbacksController |
作成したコールバック処理に転送されるように以下のようにルーティングを設定します。
1 | Rails.application.routes.draw do |
github 認証確認
アプリケーションを起動し、http://localhost:3000/users/sign_in
にアクセスします。
「Sign in with Github」をクリックします。
すると、以下の画面に進みます。
認証できると、devise でアプリケーションで設定したログイン後のリダイレクト先(何もしなければ root)にリダイレクトされます。
データベースを参照すると、User が 1 件増えていることが確認できます。
github 認証を実装できました。
プロバイダーを作ってみる
github 認証を実装できました。
今度は、github の代わりに認証自体をしてくれるプロバイダを作成してみます。
devise を導入したユーザー認証する環境を用意
こちらでも devise を使ったユーザー認証をする環境が必要なので、作成します。
Ruby on Rails での認証(Devise ライブラリ)を参照してもらえるといい。
ポート変更
ポート 3000 番で立ち上げるクライアントと同居させるので、プロバイダ側のポートを変更します。
今回は、5000 番にします。
1 | port ENV.fetch("PORT") { 5000 } |
OAuth で使うカラムを追加
User モデルに、uid
カラムを追加します。
以下の内容でマイグレーションをします。
1 | class AddColumnsToUsers < ActiveRecord::Migration[5.2] |
追加した uid を設定するため、データが追加されたときに、uid を設定するようにしておきます。
1 | class User < ApplicationRecord |
doorkeeper を導入
OAuth のプロバイダの仕組みを提供する gem、doorkeeper
を導入します。
1 | gem 'doorkeeper' |
gem が導入できたら、以下の手順で doorkeeper 用のマイグレーションまで進めます。
1 | bundle exec rails g doorkeeper:install |
config/initializers/doorkeeper.rb
が作成されているので、
以下のように編集します。
1 | Doorkeeper.configure do |
セッション作成時に、認証を要求したクライアントへリダイレクトする設定を作成します。
1 | bundle exec rails g controller users/sessions |
app/controllers/users/sessions_controller.rb
が作成されるので、以下の様に編集します。
参考元から、そのまま使わせてもらいます。
1 | class Users::SessionsController < Devise::SessionsController |
続いて、データを提供する API を作成します。
app/controllers/api/api_controller.rb
app/controllers/api/users_controller.rb
の 2 つを作成します。
1 | class Api::ApiController < ApplicationController |
1 | class Api::UsersController < Api::ApiController |
最後に、ルーティングの設定を行います。config/routes.rb
を以下のように編集します。
1 | Rails.application.routes.draw do |
プロバイダ確認
アプリケーションを起動し、http://localhost:5000/users/sign_in
にアクセスします。
ユーザーを作成します。
テーブルを確認して、uid
が追加されていることを確認しておきます。
続いてhttp://localhost:5000/oauth/applications
にアクセスします。
すると、以下の画面になります。
以下のように設定して、登録しておきます。
UID と Secret を控えておきます。
プロバイダを作成して、次に作るアプリケーションを登録できました。
自作プロバイダに対して、OAuth 認証してみる
最初に作成した github 認証したアプリケーションを自作したプロバイダでも認証できるようにします。
自作プロバイダを認証できるように調整する。
必要な gem omniauth-oauth2 を導入します。
以下を Gemfile に追記して、インストールします。
1 | gem 'omniauth-oauth2' |
omniouth が提供しないプロバイダで認証するには、ストラテジを自作する必要があります。
lib/omniauth/strategies/myapp.rb を作成します。
1 | require 'omniauth-oauth2' |
config/initializers/devise.rb を編集して myapp をプロバイダとして登録します。
1 | # 明示的に呼び出さないと、読み込まなかったので注意 |
app/models/user.rb を編集して、myapp 用の処理を作ります。
1 | class User < ApplicationRecord |
app/controllers/omniauth_callbacks_controller.rb を編集して myapp 用の処理を追加します。
1 | class OmniauthCallbacksController < Devise::OmniauthCallbacksController |
自作プロバイダで認証確認
クライアント側のアプリケーションで/users/sign_in
にアクセスすると、「Sign in with Myapp」というリンクが増えているので、こちらにアクセスします。
すると、次のようにアクセスを許可するかの画面が表示されます。
「Authorize」をクリックします。
すると、クライアントのログイン後のリダイレクト先に戻ります。
データベースを確認すると、クライアントの user にプロバイダの user と uid の同じものが作成されています。
自作のプロバイダで認証できました。
github と自作プロバイダで OAuth 認証をしてみました。
最終的にできる動作確認ができるまで足かけ 3 日程かけてしまいました。
参照している資料そのままの部分の多いのですが、自身で認証のプロバイダの実装をしてみることで、ただ使っているだけよりも理解が深まったと感じます。
何かサービスを作ることがあれば、今回のようにユーザーの管理をプロバイダに任せ、アプリケーションを分離させるのもよさそうです。
ただ、OAuth での認証を提供しているのは Google や github の様に大規模なサービスばかりです。
だからこそ認証の機能を任せる意味があるのではと考えたところでした。
認証を以外の使い方も試みてみたいところです。
ではでは。