Rails で QiitaのOmniAuthを使ってログインしてみた

動機

友人たちと、Qiitaのリーダーアプリを作成することになり、全員の勉強も兼ねて、Rails × Swift で作成することになった. しかし、gemのバージョンがもう対応していなかったり、QiitaのOmniAuthに関して、実際に使ってみた記事がほとんどなかったりして困ったので、この機会にまとめておきたいと思った。

方針

基本的には、Devise+OmniAuthでユーザ認証を実装する手順,こちらのサイトを参考にして、実装していく。

  1. devise の設定
  2. OAuth の設定

実装

1. devise の設定

まず、Gemfileに下記を追加する

gem 'devise'
$ bundle install
$ rails s

次にdevise用の設定をし、userモデル関連の設定をしていく。

$ rails g devise:install
$ rails g devise user
$ rails g devise:views user
$ rails db:create db:migrate

このコマンドで基本的な設定ファイルは作成し、users テーブルの作成も完了しているはずです。 サーバーを立ち上げ、 http://localhost:3000/users/sign_up にアクセスし、新規登録画面が表示されることを確認してみてください。

2.OmniAuthの基本実装

  1. Gemfileを編集し、インストール
gem 'omniauth'
gem 'omniauth_qiita'
$ bundle install
  1. OmniAuth に必要なカラムを追加
$ rails g migration AddColumnsToUsers uid:string provider:string
$ rails db:migrate
  1. 設定に必要なCLIENT_ID, CLIENT_SECRET を取得

https://gyazo.com/41718eb11a5ebbd86fd7bbb580f444c1.gifgyazo.com

このように、アプリケーション登録のページに移動し、必要な欄を埋めます。 redirect_url は http://localhost:3000/users/auth/qiita/callback としました。 ここ何気に重要

再度先ほどの設定画面にアクセスし、今登録したアプリケーションの詳細ページに行きます。

  1. 環境変数の設定 まず、Gemfileに次の記述を追加し、インストールします。
gem 'dotenv-rails'
$ bundle install

次に、アプリケーションディレクトリで、ターミナルから、 vim .env.sample を入力し、開いたページで次のように記述してください。

QIITA_CLIENT_ID     = ''
QIITA_CLIENT_SECRET = ''

その後ターミナルで次のコマンドを実行してください。

$ cp .env.sample .env

この操作が完了したら、.gitignoreに.envを追加しましょう そして、.envのファイルの方にのみ、先ほど取得した環境変数を追加しましょう。

.env

QIITA_CLIENT_ID     = 'ここに取得したCLIENT_IDを入力してください'
QIITA_CLIENT_SECRET = 'ここに取得したCLIENT_SECRETを入力してください'

これで、環境変数の設定が完了しました。 一応きちんと設定されているか確認するために、コンソールを立ち上げて確認しましょう。

$ rails c
(pry)>> ENV['QIIITA_CLIENT_ID']
(pry)>> ENV['QIIITA_CLIENT_SECRET']

これらできちんと先ほど入力した値が返ってくることを確認してください。もし返ってこなければ、どこかでtypoしている可能性があるので、確認してみましょう。(ちなみに僕はCLIENTのLとIが逆でひたすら時間を取られました。)

  1. devise と omniauth_qiita の設定 まず、deviseの設定をします。 config/initializers/devise.rbに下記の記述を追記してください。
Devise.setup do |config|

  config.omniauth :qiita, ENV['QIITA_CLIENT_ID'], ENV['QIITA_CLIENT_SECRET']
end

app/models/user.rb:omniauthable を追加する

devise :database_authenticatable, :registerable,
       :recoverable, :rememberable, :trackable, :validatable, :omniauthable #..この最後の部分を追加してください。

次に ユーザーモデルにfindメソッドを実装します。 app/models/user.rb

class User < ActiveRecord::Base
  # ...

  def self.find_for_oauth(auth)
    user = User.where(uid: auth.uid, provider: auth.provider).first

    unless user
      user = User.create(
        uid:      auth.uid,
        provider: auth.provider,
        email:    User.dummy_email(auth),
        password: Devise.friendly_token[0, 20]
      )
    end

    user
  end

  private

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

このあたりは、該当のQiitaの記事を参考にしています。

今度は、 users_controller.rb の設定をして行きます。 まず、

$ rails g controller omniauth_callbacks

このコマンドで、作成したコントローラを編集して行きます。 app/controllers/omniauth_callbacks_controller.rb

class OmniauthCallbacksController < Devise::OmniauthCallbacksController
  def qiita
    callback_from :qiita
  end

  private

  def callback_from(provider)
    provider = provider.to_s

    @user = User.find_for_oauth(request.env['omniauth.auth'])

    if @user.persisted?
      flash[:notice] = 'Success'
      sign_in_and_redirect @user, event: :authentication
    else
      session["devise.#{provider}_data"] = request.env['omniauth.auth']
      redirect_to new_user_registration_url
    end
  end
end

最後にルーティングの記述を編集しましょう。次のように編集してください。 config/routes.rb

Rails.application.routes.draw do
  devise_for :users, controllers: { omniauth_callbacks: 'omniauth_callbacks' }
end

以上で設定は終了となります。お疲れ様でした。 http://localhost:3000/users/sign_up にアクセスしてリンクが出現していることを確認してみてください。

参考