どぼじょのIT学習ブログ

高専卒土木女子がIT業界を目指してお勉強。

Omniauth

前回の devise でユーザ認証に続き、本日は omniauth(オムニオース)という gem を追加して、rails アプリに FacebookTwitter などの SNS アカウントでログインできるようにします!
今回は Github アカウントによる認証をやっていきます。
※ devise と組み合わせて使うので、devise が完了している前提で進めていきます。

目次

1.OAuth

omniauthは、OAuth2(OAuth の version2)という規格を使っています。
OAuth2の仕組みについては、以下の記事がとても参考になりました!✨✨

qiita.com

2.omniauthで Github 認証

2-1. インストール

omniauth を使うには、以下の gem をインストールします💡
例によって Gemfile に以下のように gem 名を書きます。

gem 'omniauth'
gem 'omniauth-github'

今回は Github ですが、 omniauth-twitteromniauth-facebookなどもあります😊
Gemfile が書けたらターミナルでbundle installです!

2-2. registrations_controller 作成

registrations_controller を作成し、deviseのコントローラを継承します。
コンソールで以下のコマンドを実行します!

$ rails g controller users::registrations

そうするといくつかファイルが作成されます。
その中にcontoroller/registrations_controller.rbというファイルがあるので、以下のように書きます。

class Users::RegistrationsController < Devise::RegistrationsController
  def build_resource(hash={})
    hash[:uid] = User.create_unique_string
    super
  end
end

f:id:mistyrinth:20190517155058p:plain

2-3. models/user.rb 修正

app/models/user.rbdevise:のところに1行追加します。
キャプチャの6行目です🙂

    :omniauthable, omniauth_providers: %i(github)

f:id:mistyrinth:20190517160707p:plain

また、同じファイルに以下のようにメソッドを追加します。

def self.create_unique_string
    SecureRandom.uuid
end

def self.dummy_email(auth)
    "#{auth.uid}-#{auth.provider}@example.com"
end

def self.find_for_github_oauth(auth, signed_in_resource=nil)
    user = User.find_by(provider: auth.provider, uid: auth.uid)
    
    unless user
      user = User.new(provider: auth.provider,
                      uid:      auth.uid,
                      name:     auth.info.name,
                      email:    User.dummy_email(auth),
                      password: Devise.friendly_token[0, 20]
      )
    end
    user.skip_confirmation!
    user.save
    user
end

f:id:mistyrinth:20190520143306p:plain

2-4. routes.rb 修正

routes.rbdevise_forに以下をように修正します!

devise_for :users, controllers: {
    registrations: "users/registrations",
    omniauth_callbacks: "users/omniauth_callbacks"
}

f:id:mistyrinth:20190520143612p:plain

2-5. devise.rb 修正

config/initializers/devise.rbの Oumiauth のところに以下の1行を書きます。
ちなみにENV['文字列']の文字列は環境変数であり、自分で名前をつけることができます💡

config.omniauth :github, ENV["GITHUB_ID"], ENV["GITHUB_SECRET"], scope: 'user,public_repo'

f:id:mistyrinth:20190517161727p:plain

2-6. Github操作

Github の Developer Settings で、OAuth application を新規作成します✈️
ここで rails アプリと関連づけます。

f:id:mistyrinth:20190517153641p:plain

すると Client IDClient Secret というコードが発行されます👀

2-7. envファイル作成

アプリケーションディレクトリ直下に.envファイルを作成し、以下のように書きます。

GITHUB_ID=Githubに出てきたClient ID
GITHUB_SECRET=Githubに出てきたClient Secret

これは公開してはいけないので、忘れずに.gitignore.envを追加します🤖
f:id:mistyrinth:20190517162202p:plain

Gemfile に dotenv-railsという gem を追加して、bundle installします。
これは.envファイルに書いた環境変数を有効にする gem です😎

2-8. migrationファイル追記

devise に関する migration ファイルのcreate_table :users do |t|以下の内容に追記します。

f:id:mistyrinth:20190517164523p:plain

2-9. view修正

必要に応じてviewを修正します。
私の場合はあまり色々書きませんでした🌝
devise 使ったときに自動で_links.html.erbに以下のプログラムが書かれていたので、それを使います。
f:id:mistyrinth:20190520163155p:plain

ログイン画面はこうなります!
f:id:mistyrinth:20190517175548p:plain

2-10. books_controller 修正

books_controllerにも1行追加します。

before_filter :authenticate_user!

f:id:mistyrinth:20190517175413p:plain
これでログインしているかどうかを判別し、コントローラへのアクセスを制御します。

2-11. omniauth_callbacks_controller の作成

app/controllers/users/omniauth_callbacks_controller.rbを新規作成します。
中身は以下のとおりです。

class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
  def github
    @user = User.find_for_github_oauth(request.env["omniauth.auth"], current_user)

    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
end

f:id:mistyrinth:20190517181253p:plain

2-12. i18nについて

omniaith 関連の i18n については devise-i18n の gem に含まれているので、特別何もしなくても勝手に多言語化してくれました〜!

以上です!