Rails認証gem「devise」徹底ガイド
rails ruby device1. はじめに
Railsでユーザー認証を実装する際に、真っ先に候補に挙がるのが「devise」というgemではないでしょうか。deviseは、Railsアプリケーションにユーザー認証機能を追加するための強力で柔軟なソリューションです。
deviceとは何か
deviseは、Railsアプリケーションにユーザー認証を追加するためのgemです。ユーザー登録、ログイン、ログアウト、パスワードリセット、メール確認など、認証に関連する一連の機能を提供します。deviseは、Railsのコーディング規約に沿って設計されているため、Railsの開発者にとって使いやすく、簡単に導入することができます。
deviceを使うメリット
deviseを使うメリットは以下の通りです。
実装の簡略化
- deviseは、認証に関連する複雑な処理を抽象化し、シンプルなAPIを提供します。これにより、開発者は認証機能の実装に費やす時間を大幅に削減できます。
安全性の向上
- deviseは、セキュリティの観点から設計されており、一般的な脆弱性への対策が施されています。適切な設定を行うことで、アプリケーションのセキュリティを向上させることができます。
柔軟性と拡張性
- deviseは、柔軟な設定オプションと豊富な拡張機能を提供します。これにより、アプリケーションの要件に合わせて認証機能をカスタマイズし、拡張することができます。
認証と認可の違い
認証(Authentication)と認可(Authorization)は、しばしば混同されがちな概念です。簡単に説明すると、以下のような違いがあります。
認証(Authentication)
- ユーザーが主張する身元を確認するプロセス。
- 「ユーザーが本人であることを確認する」ことが目的。
- devise gemは、主に認証を担当する。
認可(Authorization)
- ユーザーに特定のリソースへのアクセス権限を付与するプロセス。
- 「ユーザーにどの機能を使う権限があるかを決定する」ことが目的。
- pundit, cancancanなどの認可用のgemと組み合わせて使われることが多い。
認証と認可は、セキュリティの観点から両方を適切に実装する必要があります。まずは認証を実装し、その後、認可を追加するのが一般的な流れです。
次の章では、実際にdeviseをRailsアプリケーションに導入する方法について解説します。
2. deviceのインストールと設定
この章では、Railsアプリケーションへのdeviseのインストールと初期設定の方法について説明します。
Gemfileへの追加とインストール
まず、Gemfile
に以下の行を追加します。
gem 'devise'
次に、ターミナルで以下のコマンドを実行し、deviseをインストールします。
bundle install
devise関連ファイルの生成
deviseに必要なファイルを生成するために、以下のコマンドを実行します。
rails generate devise:install
このコマンドにより、devise用の設定ファイルや、環境ごとの設定を追加するための手順が表示されます。表示された手順に従って、必要な設定を行います。
モデルへのdeviseの追加
ユーザー認証を行うモデル(通常はUser
モデル)に、deviseの機能を追加します。以下のコマンドを実行します。
rails generate devise User
このコマンドにより、User
モデルにdeviseに関連するカラムが追加され、config/routes.rb
にdeviseのルーティングが追加されます。
生成されたマイグレーションファイルを確認し、必要に応じてカラムを追加したり、カスタマイズしたりします。その後、以下のコマンドでマイグレーションを実行します。
rails db:migrate
ルーティングの設定
config/routes.rb
を開き、以下のようにdeviseのルーティングが追加されていることを確認します。
Rails.application.routes.draw do
devise_for :users
# ... 他のルーティング
end
この設定により、ユーザー登録、ログイン、ログアウトなどのためのルーティングが自動的に追加されます。
devise設定ファイルの解説
config/initializers/devise.rb
は、deviseの設定を行うためのファイルです。このファイルには、多数の設定項目がコメントアウトされた状態で含まれています。必要に応じて、コメントを外して設定を変更することができます。
よく利用される設定項目には、以下のようなものがあります。
config.mailer_sender
: deviseが送信するメールのFromアドレスを設定します。config.authentication_keys
: ログインに使用するカラムを指定します。config.password_length
: パスワードの最小文字数と最大文字数を設定します。config.stretches
: パスワードのハッシュ化に使用するストレッチ回数を設定します。
これらの設定を適切に行うことで、アプリケーションの要件に合わせてdeviseの動作をカスタマイズすることができます。
次の章では、deviseが提供する主要な機能について、具体的な使い方を説明します。
3. deviceの機能と使い方
この章では、deviseが提供する主要な機能について、具体的な使い方を説明します。サンプルコードやシーケンス図を交えながら、各機能の実装方法を詳しく解説します。
ユーザー登録
ユーザー登録は、新しいユーザーがアプリケーションを利用するために必要な情報を入力し、アカウントを作成するプロセスです。
サンプルコード
app/views/devise/registrations/new.html.erb
にユーザー登録用のビューが用意されています。このファイルを編集することで、ユーザー登録フォームをカスタマイズできます。
<h2>Sign up</h2>
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<%= render "devise/shared/error_messages", resource: resource %>
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true, autocomplete: "email" %>
</div>
<div class="field">
<%= f.label :password %>
<% if @minimum_password_length %>
<em>(<%= @minimum_password_length %> characters minimum)</em>
<% end %><br />
<%= f.password_field :password, autocomplete: "new-password" %>
</div>
<div class="field">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation, autocomplete: "new-password" %>
</div>
<div class="actions">
<%= f.submit "Sign up" %>
</div>
<% end %>
<%= render "devise/shared/links" %>
登録フローのシーケンス図
ストロングパラメータの設定
ユーザー登録時に受け取るパラメータを制限するために、ストロングパラメータを設定します。app/controllers/application_controller.rb
に以下のように記述します。
class ApplicationController < ActionController::Base
before_action :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: [:name])
end
end
この例では、ユーザー登録時に:name
属性を許可しています。
ログイン・ログアウト
ログインは、登録済みのユーザーがアプリケーションにアクセスするためのプロセスです。ログアウトは、ユーザーがアプリケーションからサインアウトするプロセスです。
サンプルコード
app/views/devise/sessions/new.html.erb
にログイン用のビューが用意されています。このファイルを編集することで、ログインフォームをカスタマイズできます。
<h2>Log in</h2>
<%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true, autocomplete: "email" %>
</div>
<div class="field">
<%= f.label :password %><br />
<%= f.password_field :password, autocomplete: "current-password" %>
</div>
<% if devise_mapping.rememberable? %>
<div class="field">
<%= f.check_box :remember_me %>
<%= f.label :remember_me %>
</div>
<% end %>
<div class="actions">
<%= f.submit "Log in" %>
</div>
<% end %>
<%= render "devise/shared/links" %>
ログインフローのシーケンス図
Remember me機能の説明
Remember me機能は、ユーザーがログイン状態を維持できるようにするための機能です。ログインフォームでRemember meのチェックボックスにチェックを入れてログインすると、ユーザーのブラウザにクッキーが保存され、次回以降のアクセス時にもログイン状態が維持されます。
この機能を有効にするには、config/initializers/devise.rb
で以下の設定を行います。
config.remember_for = 2.weeks
この例では、Remember me機能でログイン状態を2週間維持するように設定しています。
次の章では、deviseのカスタマイズ方法について説明します。
4. deviceのカスタマイズ
この章では、deviseの機能をアプリケーションの要件に合わせてカスタマイズする方法について説明します。コントローラー、ビュー、モデルのカスタマイズ方法を具体的に解説します。
コントローラーのカスタマイズ
devise_controllerの使用
deviseのコントローラーをカスタマイズするには、devise_controller
メソッドを使用します。このメソッドを使うことで、deviseのコントローラーを継承したカスタムコントローラーを作成できます。
class Users::RegistrationsController < Devise::RegistrationsController
before_action :configure_sign_up_params, only: [:create]
protected
def configure_sign_up_params
devise_parameter_sanitizer.permit(:sign_up, keys: [:name])
end
end
この例では、Users::RegistrationsController
を作成し、Devise::RegistrationsController
を継承しています。configure_sign_up_params
メソッドを定義し、ユーザー登録時に:name
属性を許可しています。
コントローラーの継承とオーバーライド
deviseのコントローラーの動作をカスタマイズするには、対応するアクションをオーバーライドします。
class Users::SessionsController < Devise::SessionsController
def create
super do |resource|
# ログイン後の処理を追加
end
end
end
この例では、Users::SessionsController
を作成し、Devise::SessionsController
を継承しています。create
アクションをオーバーライドし、ログイン後の処理を追加しています。
ビューのカスタマイズ
devise_controllableの使用
deviseのビューをカスタマイズするには、devise_controllable
メソッドを使用します。このメソッドを使うことで、deviseのビューを生成するためのコマンドを実行できます。
rails generate devise:views users
このコマンドを実行すると、app/views/users/
ディレクトリにdeviseのビューファイルが生成されます。
ビューの生成とカスタマイズ
生成されたビューファイルを編集することで、deviseのビューをカスタマイズできます。例えば、app/views/users/registrations/new.html.erb
を編集することで、ユーザー登録ページをカスタマイズできます。
<h2>Sign up</h2>
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<%= render "users/shared/error_messages", resource: resource %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name, autofocus: true %>
</div>
<!-- 他のフィールド -->
<div class="actions">
<%= f.submit "Sign up" %>
</div>
<% end %>
<%= render "users/shared/links" %>
この例では、ユーザー登録ページに:name
属性の入力フィールドを追加しています。
モデルのカスタマイズ
バリデーションの追加
deviseで認証に使用するモデルにバリデーションを追加することで、ユーザー登録時のデータ検証をカスタマイズできます。
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
validates :name, presence: true
end
この例では、User
モデルに:name
属性の存在チェックを追加しています。
コールバックの利用
deviseでは、認証プロセスの各段階でコールバックを利用できます。コールバックを使うことで、認証前後の処理を追加できます。
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
after_create :send_welcome_email
private
def send_welcome_email
# ウェルカムメールを送信する処理
end
end
この例では、User
モデルにafter_create
コールバックを追加し、ユーザー登録後にウェルカムメールを送信する処理を実装しています。
次の章では、複数のユーザー種類に対応する方法について説明します。
5. 複数のユーザー種類への対応
アプリケーションによっては、複数のユーザー種類(例: 一般ユーザーと管理者)を扱う必要がある場合があります。この章では、複数のユーザー種類に対応する方法について説明します。
複数のモデルでdeviseを使う方法
複数のユーザー種類に対応するために、それぞれのユーザー種類に対応するモデルを作成します。各モデルに対してdeviseを設定します。
# app/models/user.rb
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
end
# app/models/admin.rb
class Admin < ApplicationRecord
devise :database_authenticatable, :rememberable, :validatable
end
この例では、User
モデルとAdmin
モデルを作成し、それぞれにdeviseを設定しています。
モデル毎のルーティング設定(devise_scope)
各モデルに対応するdeviseのルーティングを設定するために、devise_scope
を使用します。
# config/routes.rb
Rails.application.routes.draw do
devise_for :users
devise_for :admins, skip: :registrations
devise_scope :admin do
get 'admins/edit', to: 'admins/registrations#edit', as: 'edit_admin_registration'
put 'admins', to: 'admins/registrations#update', as: 'admin_registration'
end
end
この例では、User
モデルとAdmin
モデルに対してdeviseのルーティングを設定しています。Admin
モデルでは、登録機能をスキップし、編集機能のみを有効にしています。
モデル毎のコントローラー・ビューの作成
各モデルに対応するコントローラーとビューを作成します。
rails generate devise:controllers users
rails generate devise:controllers admins
rails generate devise:views users
rails generate devise:views admins
これらのコマンドを実行すると、各モデルに対応するコントローラーとビューが生成されます。生成されたファイルを編集することで、各ユーザー種類に固有の機能を実装できます。
次の章では、deviseの拡張機能について説明します。
6. deviceの拡張機能
deviseは、認証に関連する様々な拡張機能を提供しています。この章では、代表的な拡張機能について説明します。
Omniauth(外部認証)との連携
OmniAuthは、外部サービス(Google、Facebook、Twitterなど)を利用した認証を実現するためのgemです。deviseとOmniAuthを連携させることで、外部サービスを利用したユーザー認証を簡単に実装できます。
OmniAuthの設定
まず、Gemfile
に必要なgemを追加します。
gem 'omniauth-google-oauth2'
gem 'omniauth-facebook'
gem 'omniauth-twitter'
次に、config/initializers/devise.rb
にOmniAuthの設定を追加します。
config.omniauth :google_oauth2, 'GOOGLE_CLIENT_ID', 'GOOGLE_CLIENT_SECRET', scope: 'email'
config.omniauth :facebook, 'FACEBOOK_APP_ID', 'FACEBOOK_APP_SECRET'
config.omniauth :twitter, 'TWITTER_API_KEY', 'TWITTER_API_SECRET'
各サービスのクライアントIDとシークレットを設定します。
コールバック処理の実装
OmniAuthのコールバック処理を実装するために、Users::OmniauthCallbacksController
を作成します。
# app/controllers/users/omniauth_callbacks_controller.rb
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
def google_oauth2
# Googleアカウントを利用したログイン処理を実装
end
def facebook
# Facebookアカウントを利用したログイン処理を実装
end
def twitter
# Twitterアカウントを利用したログイン処理を実装
end
end
各サービスからのコールバックに対応するアクションを定義し、必要な処理を実装します。
Confirmable(メール確認)の設定
Confirmableは、ユーザー登録時にメールアドレスの確認を行うための機能です。
Confirmableの有効化
User
モデルに:confirmable
を追加します。
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable,
:confirmable
end
マイグレーションファイルに:confirmation_token
、:confirmed_at
、:confirmation_sent_at
カラムを追加します。
add_column :users, :confirmation_token, :string
add_column :users, :confirmed_at, :datetime
add_column :users, :confirmation_sent_at, :datetime
add_index :users, :confirmation_token, unique: true
メール確認フローの解説
- ユーザーがサインアップすると、確認メールが送信される
- ユーザーは、メールに記載された確認リンクをクリックする
- 確認リンクから
Users::ConfirmationsController#show
アクションが呼び出される - ユーザーの
confirmed_at
属性が更新され、メールアドレスが確認済みになる
Lockable(アカウントロック)の設定
Lockableは、一定回数のログイン失敗によるアカウントのロックを行うための機能です。
Lockableの有効化
User
モデルに:lockable
を追加します。
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable,
:lockable
end
マイグレーションファイルに:failed_attempts
、:locked_at
カラムを追加します。
add_column :users, :failed_attempts, :integer, default: 0
add_column :users, :locked_at, :datetime
ロック解除方法の解説
アカウントがロックされた場合、以下の方法でロックを解除できます。
- 一定時間経過後に自動的にロックが解除される(デフォルトでは1時間)
- ユーザーが手動でロック解除のリクエストを送信する
Users::UnlocksController#new
アクションでロック解除リクエストのフォームを表示Users::UnlocksController#create
アクションでロック解除メールを送信- ユーザーがロック解除メールのリンクをクリックすることでアカウントがロック解除される
二要素認証の実装
二要素認証は、パスワードに加えて別の認証方法を組み合わせることで、セキュリティを強化する手法です。
gem ‘devise-two-factor’の利用
devise-two-factor
gemを使用することで、deviseに二要素認証を追加できます。
gem 'devise-two-factor'
User
モデルに:two_factor_authenticatable
を追加します。
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable,
:two_factor_authenticatable
end
二要素認証フローの解説
- ユーザーがログインすると、パスワードの認証が行われる
- パスワードの認証が成功すると、二要素認証コードの入力が求められる
- ユーザーは、事前に設定した二要素認証デバイス(Google Authenticatorなど)から認証コードを取得する
- ユーザーが認証コードを入力し、認証が成功するとログインが完了する
次の章では、RSpecを使ったdeviseのテストについて説明します。
7. RSpecを使ったdeviseのテスト
アプリケーションの品質を維持するために、deviseの機能に対するテストを書くことが重要です。この章では、RSpecを使ってdeviseのコントローラーとモデル、およびフィーチャースペックのテストを書く方法について説明します。
コントローラーのテスト
deviseのコントローラーをテストするために、devise
とdevise_controller
をテストに含める必要があります。
# spec/controllers/users/registrations_controller_spec.rb
require 'rails_helper'
RSpec.describe Users::RegistrationsController, type: :controller do
before do
@request.env["devise.mapping"] = Devise.mappings[:user]
end
describe 'POST #create' do
context 'パラメータが有効な場合' do
it 'ユーザーが作成される' do
expect {
post :create, params: { user: attributes_for(:user) }
}.to change(User, :count).by(1)
end
end
context 'パラメータが無効な場合' do
it 'ユーザーが作成されない' do
expect {
post :create, params: { user: attributes_for(:user, email: '') }
}.not_to change(User, :count)
end
end
end
end
この例では、Users::RegistrationsController
のcreate
アクションをテストしています。有効なパラメータが渡された場合にユーザーが作成されること、無効なパラメータが渡された場合にユーザーが作成されないことをテストしています。
モデルのテスト
deviseのモデルに追加したバリデーションやコールバックをテストします。
# spec/models/user_spec.rb
require 'rails_helper'
RSpec.describe User, type: :model do
describe 'バリデーション' do
it 'メールアドレスが必須であること' do
user = build(:user, email: '')
expect(user).not_to be_valid
end
it 'パスワードが必須であること' do
user = build(:user, password: '')
expect(user).not_to be_valid
end
end
describe 'コールバック' do
it 'ユーザー作成後にウェルカムメールが送信されること' do
expect {
create(:user)
}.to change { ActionMailer::Base.deliveries.count }.by(1)
end
end
end
この例では、User
モデルのバリデーションとコールバックをテストしています。メールアドレスとパスワードが必須であること、ユーザー作成後にウェルカムメールが送信されることをテストしています。
フィーチャースペックの作成
フィーチャースペックを使ってdeviseの機能を統合的にテストします。
# spec/features/user_registration_spec.rb
require 'rails_helper'
RSpec.feature 'ユーザー登録', type: :feature do
scenario 'ユーザーが新規登録する' do
visit new_user_registration_path
fill_in 'Email', with: '[email protected]'
fill_in 'Password', with: 'password'
fill_in 'Password confirmation', with: 'password'
click_button 'Sign up'
expect(page).to have_content 'Welcome! You have signed up successfully.'
end
end
この例では、ユーザー登録のフィーチャースペックを書いています。ユーザー登録ページを訪問し、フォームに必要な情報を入力して送信すると、ユーザー登録が成功することをテストしています。
同様に、ログインやパスワードリセットなどの機能に対するフィーチャースペックを書くことで、deviseの機能が期待通りに動作することを確認できます。
8. まとめ
- deviseは、Railsアプリケーションにユーザー認証機能を追加するための強力で柔軟なソリューションです。
- deviseのインストールと初期設定を行うことで、すぐにユーザー認証機能を利用できます。
- deviseの各機能(ユーザー登録、ログイン・ログアウト、パスワードリセット、メール確認など)の使い方を理解することが重要です。
- コントローラー、ビュー、モデルをカスタマイズすることで、アプリケーションの要件に合わせてdeviseの動作を変更できます。
- 複数のユーザー種類に対応する場合は、それぞれのモデルに対してdeviseを設定し、ルーティングやコントローラー、ビューを適切に設定する必要があります。
- OmniAuthやConfirmable、Lockableなどの拡張機能を利用することで、より高度なユーザー認証機能を実現できます。
- RSpecを使ってdeviseのコントローラーやモデル、フィーチャースペックのテストを書くことで、アプリケーションの品質を維持できます。
- ユーザー認証は、アプリケーションのセキュリティにとって非常に重要な機能です。適切に実装し、定期的にテストを行うことが求められます。
deviseは、Railsアプリケーションにユーザー認証機能を追加するための強力なツールです。この記事で説明した内容を理解し、適用することで、セキュアで使いやすいユーザー認証機能を実現できるでしょう。
以上が、Railsのdeviseについての詳細な解説記事のアウトラインとサンプルコードです。実際の記事では、各章の内容をさらに詳しく説明し、具体的なコードやイメージを交えながら、初心者にも理解しやすい文章で書くことが重要です。また、deviseの公式ドキュメントやその他の関連資料へのリンクを提供することで、読者がより深く学ぶことができるようにするとよいでしょう。