Tech Racho エンジニアの「?」を「!」に。
  • 開発

Rails tips: DeviseとOmniAuth認証でLinkedIn機能にサインインする(翻訳)

概要

原著者の許諾を得て翻訳・公開いたします。

Rails tips: DeviseとOmniAuth認証でLinkedIn機能にサインインする(翻訳)

本記事ではRuby 2.5 + Rails 5.1.4を用います。執筆時点ではいずれも最新です。まずはGemfileにDevise gemを追加しましょう。

gem 'devise'

続いてbundle installを実行してPCにgemをインストールしなければなりません。しかしインストールはこれだけでは終わりません。以下のコマンドを実行して、Deviseのイニシャライザファイルと翻訳ファイルを生成しなければなりません。

rails generate devise:install

モデルの生成

これでモデルを生成できるようになりました。認証データを持つモデル名はUserとするのが普通なので、この名前にします。

rails generate devise user

上のコマンドでDeviseがモデルのクラスとマイグレーションとカラのテストを生成してくれます。Userモデルの内容は次のようになっています。

class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable
end

アプリではLinkedInの認証のみを許可したいので、不要なコードを削除します。

class User < ApplicationRecord
  devise :trackable, :omniauthable
end

マイグレーションの内容は次のようになっているはずです。

# frozen_string_literal: true

class DeviseCreateRecruiters < ActiveRecord::Migration[5.1]
  def change
    create_table :users do |t|
      t.string :email,              null: false, default: ""

      ## Trackable
      t.integer  :sign_in_count, default: 0, null: false
      t.datetime :current_sign_in_at
      t.datetime :last_sign_in_at
      t.inet     :current_sign_in_ip
      t.inet     :last_sign_in_ip

      # LinkedIn
      t.string :provider
      t.string :uid, unique: true

      t.timestamps null: false
    end

    add_index :users, :email,                unique: true
  end
end

ここではメールとパスワードによる認証は使いたくありませんが、後で使えるようにアプリにはユーザーのメールを保存しておきたいと思います。データベースにテーブルを作成するために以下のマイグレーションを実行しなければなりません。

bundle exec rake db:migrate

不要なカラムが残っていることに気づいた場合は、マイグレーションをロールバックしてファイルを修正し、再度マイグレーションを実行できます。

bundle exec rake db:rollback STEP=1

OmniAuthストラテジーによるLinkedIn認証では、providerカラムとuidカラムを使います。

LinkedInの設定

認証にはomniauth-linkedin gemを使いますので、最初にインストールしておきましょう。Gemfileに以下の行を追加してbundle installを実行します。

gem 'omniauth-linkedin'

今度はアプリでconsumer_keyconsumer_secretキーが必要になります。アプリにこれらがない場合はこちらの記事を参考に作成しておいてください。

config/initializers/devise.rbにあるDevise gemイニシャライザを開いて、credenntialを追加します。

config.omniauth :linkedin, "consumer_key", "consumer_secret"

これで、Userモデルを更新して認証プロバイダとしてLinkedInを使うよう指定できるようになります。

class User < ApplicationRecord
  devise :trackable, :omniauthable, omniauth_providers: %i[linkedin]
end

ルーティング

config/routes.rbにdevise_for :usersエントリがあれば、Deviseによって自動的に以下の2つのパスが追加されます。

  • user_omniauth_authorize_path(provider)
  • user_omniauth_callback_path(provider)

これで、LinkedIn認証を開始するためのリンクを追加できます。

<%= link_to "Sign in with LinkedIn", user_linkedin_omniauth_authorize_path %>

このリンクをクリックするとLinkedIn認証ページにリダイレクトされます。今度は、コントローラでリクエストを受けて、指定のユーザーをアプリ側で認証する準備をしなければなりません。

認証コントローラ

認証アクションを扱うために、別のコントローラを作成することにします。このコントローラの名前はAuthorizationsControllerにしました。LinkedInリクエストを処理するために、linkedinメソッドとfailureメソッドの追加が必要です。1番目のメソッドはレスポンスが成功した場合を扱い、2番目は失敗の場合を扱います。

class AuthorizationsController < Devise::OmniauthCallbacksController
  def linkedin
  end

  def failure
    redirect_to root_path
  end
end

上のコードが機能するには、ルーティングファイルを更新して、LinkedIn認証に使うコントローラがどれであるかをDeviseに伝えなければなりません。

devise_for :users, controllers: { omniauth_callbacks: 'authorizations' }

それでは、ユーザーの作成と検索を担当するコードを実装しましょう。

def self.from_omniauth(auth)
  where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
    user.email = auth.info.email
  end
end

コントローラを更新して、認証が完全に動作するようにしましょう。

class AuthorizationsController < Devise::OmniauthCallbacksController
  def linkedin
    @user = User.from_omniauth(request.env["omniauth.auth"])

    sign_in_and_redirect @user, event: :authentication
  end

  def failure
    redirect_to root_path
  end
end

これでおしまいです。LinkedInネットワーク経由でユーザーを認証できる非常にシンプルな基本アプリを作りました。保存されるのはメールだけです。名前や画像といった他のデータを集めることもできます。可能性は無限なので、何をするかはあなた次第です。

ユーザーが認証されれば、コントローラやビューでcurrent_userを介してアクセスできるようになります。

お知らせ: RSpec & TDDの電子書籍を無料でダウンロード

もっと稼ぎたい方や会社をさらに発展させたい方へ: テスティングのスキルの重要性にお気づきでしょうか?テストを正しく書き始めることが、唯一のファーストステップです。無料でダウンロードいただける私の書籍『RSpec & Test Driven Developmentの無料ebook』をどうぞお役立てください。

関連記事

[Rails] Devise Wiki日本語もくじ1「ワークフローのカスタマイズ」(概要・用途付き)


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。