omniauthを使ってGitHubでログインする機能を実装すると宣言したのですが、omniauthはdeviseに入ってました。

なのでdeviseを使いました。

devise

準備

まずアプリ作成(てきとう)

1
2
3
$ rails new github_login_sample
$ cd github_login_sample
$ rails g scaffold Blog title body:text

Gemfileに下記を追加

1
2
3
gem 'devise'
gem 'omniauth-github'
gem "figaro"

deviseのinstall等

1
2
3
4
5
6
$ bundle
$ rails g devise:install
$ rails g devise User
$ rails g migration AddColumnsToUsers provider uid
$ rake db:migrate
$ rails g figaro:install

figaro

figaroをインストールすると config/application.yml が作成され、.gitignore に下記が追加されます

1
/config/application.yml

application.yml には下記のようにAPP_IDAPP_SECRETを書きます。

1
2
APP_ID: xxxxxxxxxxxxxxxxxxxx
APP_SECRET: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

あ、これはGithubの Settings/Apprications/Register new application でアプリを登録すると発行されます。

そして config/initializers/devise.rb

1
  config.omniauth :github, ENV["APP_ID"], ENV["APP_SECRET"], scope: 'user,public_repo'

と書くわけです。application.yml に書いた名称と同じなら、APP_IDとかじゃなくても、何でもいいです。

application.yml がgit管理対象外になっているので、githubに上げてもAPP_IDAPP_SECRETが知られなくていいですね。(privateリポジトリなら関係ないけど)

routes

次はconfig/routes.rb へ下記を追加。callbackのルーティングです。

1
2
3
4
5
6
  root 'blogs#index'
  get 'blogs/index'
  devise_for :users, :controllers => { :omniauth_callbacks => "users/omniauth_callbacks" }
  devise_scope :user do
    get 'sign_out', :to => 'devise/sessions#destroy', :as => :destroy_user_session
  end

controller

それから app/controller/users/omniauth_callbacks_controller.rb を追加します。 callback時のログイン処理です。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
  def github
    @user = User.find_or_create_by(user_params)

    if @user.persisted?
      sign_in_and_redirect @user, :event => :authentication
      set_flash_message(:notice, :success, :kind => "Github") if is_navigational_format?
    else
      session["devise.github_data"] = request.env["omniauth.auth"]
      redirect_to new_user_registration_url
    end
  end

  private
  def user_params
    request.env["omniauth.auth"].slice(:provider, :uid).to_h
  end
end

model

app/models/user.rb に下記を追加。もうちょっとです。

1
2
3
class User < ActiveRecord::Base
  devise :omniauthable
end

view

viewにSign in、Sign outを追加します。

1
2
3
4
5
<% if user_signed_in? %>
    <%= link_to "Sign out", destroy_user_session_path %>
<% else %>
    <%= link_to "Sign in with Github", user_omniauth_authorize_path(:github) %>
<% end %>

そして

あとはログイン後に表示する箇所を

1
2
3
<% if user_signed_in? %>

<% end %>

でくくるとか、controllerで認証処理を書けばいいわけです。


参考

参考にさせていただきました。 devise gemを使ってtwitter認証の設定