Rails
devise
Gem

DeviseのREADMEを翻訳してみた

この記事は、2015年6月8日現在の翻訳です。

これ以降の変更は対応していません。


Devise

DeviseはWardenベースのRails用認証ソリューションです。

Deviseは以下の特徴があります。


  • Rackベース

  • Railsエンジンで動作する完全なMVCソリューション

  • 同時に複数のモデルでサインイン可能

  • 本当に必要なモノだけを使えるようなモジュール方式のコンセプト

次の10のモジュールから構成されています。


  • Database Authenticable: ユーザがサインインするための認証パスワードを暗号化しDBに保存します

  • Omniauthable: OmniAuthをサポートします

  • Confirmable: 確認フロー中にメールを送付し、サインインの際にアカウントが確認済みか否かをチェックします

  • Recoverable: パスワードのリセットをし、リセット方法をメールで送付します

  • Registerable: 登録プロセスを通してユーザのサインアップを行い、ユーザ情報の編集や削除機能を有します

  • Rememberable: ユーザ情報をクッキーに保存するため、トークンを生成・削除します

  • Trackable: サインイン回数、サインイン時間、IPアドレスを保存します

  • Timeoutable: 特定の時間でセッションの有効期限を切ることができます

  • Validatable: emailとパスワードのバリデーションが可能です。これはオプションであり、カスタマイズ可能であるため、独自バリデーション機能を定義できます

  • Lockable: サインインに特定の回数失敗したのち、アカウントをロックします。メールもしくは特定の時間ののちアンロック可能です


Information


The Device Wiki

The Devise Wikiには、たくさんの"how to"記事やFAQを含む情報があります。READMEを読んだ後、見に行ってください。

https://github.com/plataformatec/devise/wiki


Bug reports

Deviseに問題を発見したら、教えてほしいです。以下のガイドラインを読んだ後、バグレポートをあげてください。

https://github.com/plataformatec/devise/wiki/Bug-reports

万が一セキュリティ関連のバグを発見した場合は、GitHubのイシュートラッカーを利用しないでください。以下のメールアドレスへ連絡ください。

opensource@plataformatec.com.br


Mailing list

質問、コメントなどは、GitHubイシュートラッカーではなく、Google Groupsを利用してください。

https://groups.google.com/group/plataformatec-devise


RDocs

DeviseのドキュメントはRDocフォーマットでも利用可能です。

http://rubydoc.info/github/plataformatec/devise/master/frames

以前のバージョンのRailsでDeviseを利用する必要がある場合は、過去のドキュメントを確認するため、gemをインストールしたのち、"gem server"をコマンドラインで走らせてください。


Example applications

複数のバージョンのRails上でDeviseの各種機能を動作させるデモアプリケーションサンプルをGitHubで入手可能です。

https://github.com/plataformatec/devise/wiki/Example-Applications


Extensions

コミュティでは、Deviseを高機能にするたくさんのextensionを作成しています。以下のページで入手可能なextensionのリストを閲覧・入手できます。

https://github.com/plataformatec/devise/wiki/Extensions


Contributing

Deviseへの貢献をお待ちしております。以下の概要を確認してください。

https://github.com/plataformatec/devise/wiki/Contributing

変更に対してはテストを書くと思います。テストスイートを走らせる場合は、Deviseのトップディレクトリを行き、"bundle install"および"rake"を実行してください。テストをパスさせるため、システムにはMongoDBサーバ(2.0以上)が必要になります。


Starting with Rails?

もし、Railsアプリケーションの構築が初めての場合は、Deviseはおすすめしません。DeviseはRailsフレームワークを熟知する必要があります。スクラッチで一度シンプルな認証システムを構築することをおすすめします。次の2つのリソースが参考になるでしょう。

Railsと認証の仕組みを理解したのち、Deviseは非常に有用だとわかります :smiley:


Getting started

Devise 3.0は、Rails 3.2以上で動作します。Gemfileに追加します。

gem 'devise'

bundleコマンドを実行してください。

Deviseをインストールした後、generatorを実行してください。

rails generate devise:install

generatorは、全てのDevise設定オプションのinitializerをインストールします。一度、必ず確認してください。終わったら、generatorを利用してDeviseを好きなモデルに追加してください。

rails generate devise MODEL

MODELはアプリケーションのユーザを表す名前のクラスに書き換えてください(Userであることが多いですが、Adminかもしれません)。これにより、(もし存在しなければ)モデルが生成され、Deviseモジュールとして設定されます。generatorは、config/routes.rbファイルもDeviseコントローラを指すように修正します。

次に、メール確認やアカウントロックなどのモデルに追加したいオプション設定をチェックしてください。オプションを追加した場合は、(ORMがサポートしていればgeneratorによって作成される)migrationファイルも確認し、適切なセクションのコメントを外してください。例えば、メール確認のオプションを追加した場合、Confirmableセクションのコメントを外す必要があります。そのあとrake db:migrateを実行してください。

次は、各環境のDevise用メールサーバの設定をします。以下は、config/environments/development.rb用の設定例です。

config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }

Deviseの設定を変更したら、アプリケーションを再起動してください。再起動しないと、ログインできなかったりルーティング設定が壊れているというエラーが発生する可能性があります。


Controller filters and helpers

Deviseは、controllerやviewで利用可能なhelperを生成します。ユーザ認証をcontrollerに設定するには、before_actionを追加するだけです(以下は、Deviseのmodelが'User'の例です)。

before_action :authenticate_user!

DeviseのmodelがUserではない場合、"_user"の部分を"_yourmodel"に変更してください。これから紹介する内容が利用できるようになります。

ユーザがサインイン済みかをチェックするには、次のhelperを利用します。

user_signed_in?

現在サインイン中のユーザについては、このhelperが利用可能です。

current_user

セッションにもアクセスできます。

user_session

サインイン、アカウントの確認、パスワードの変更などを行った後、Deviceは画面をリダイレクトするためrootパスを探します。例えば、:userリソースを利用しているのであれば、user_root_pathが存在しているなら、それが使われます。そうでなければ、デフォルトのroot_pathが使われます。つまり、ルーティングにrootを設定する必要があるということです。

root to: "home#index"

さらに、after_sign_in_path_forafter_sign_out_path_forをオーバーライドしてリダイレクトフックをカスタマイズできます。

DeviseのmodelがUserではなくMemberの場合、以下のようなhelperが利用可能です。

before_action :authenticate_member!

member_signed_in?

current_member

member_session


Configuring Models

model内のDeviseメソッドで、該当のモジュールの設定を行うことが可能です。例えば、以下のように暗号化アルゴリズムの選択が可能です。

devise :database_authenticatable, :registerable, :confirmable, :recoverable, :stretches: 20

:stretchesでは、 :pepper:encryptor:confirm_within:remember_for:timeout_in:unlock_in のオプションを定義できます。さらに詳しい情報は、上で説明した"devise:install"のgeneratorが呼び出されたときに生成されたinitializerファイルを確認してください。このファイルは通常、/config/initializers/devise.rbにあります。


Strong Parameters

独自ビューをカスタマイズする際に、フォームに新しい属性を追加する必要があります。Rails 4では、パラメータのサニタイズをmodelからcontrollerへ移しました。これにより、Deviseはcontrollerでもこの問題を扱えるようになりました。

サニタイズが必要な場合、Deviseでは3つのアクションによりmodelへ各パラメータを渡すことができます。デフォルトでは以下の名前とパラメータになります。



  • sign_in(Devise::SessionsController#create) - 認証キー(例えばemail)のみを許可します


  • sign_up(Devise::RegistrationsController#create) - 認証キーに加え、passwordpassword_confirmationを許可します


  • account_update(Devise::RegistrationsController#update) - 認証キーに加え、passwordpassword_confirmationcurrent_passwordを許可します

もしその他のパラメータを追加した場合は(the lazy way:tm:)、ただbeforeフィルタをApplicationControllerを追加します。

class ApplicationController < ActionController::Base

before_action :configure_permitted_parameters, if: :devise_controller?

protected

def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) << :username
end
end

上記のコードは、パラメータが単純なスカラータイプである場合どんな追加パラメータでも動作します。ネストされた属性の場合(accepts_nested_attributes_forを利用している場合)、ネストされていることとそのタイプをDeviseに伝える必要があります。デフォルト設定を全部変更したり、カスタマイズした振る舞いをさせることもできます。

ユーザ名とemailを許可する場合は以下のようにします。

def configure_permitted_parameters

devise_parameter_sanitizer.for(:sign_in) { |u| u.permit(:username, :email) }p
end

もし、登録の際にユーザにロールを割り当てるためのチェックボックスがある場合は、ブラウザはチェックボックスを配列で渡します。配列は、Strong Parameterで許可されていないため、以下のようにDeviseを設定する必要があります。

def configure_permitted_parameters

devise_parameter_sanitizer.for(:sign_up) { |u| u.permit({ roles: [] }, :email, :password, :password_confirmation) }
end

許可値リストや、ネストしたハッシュや配列からキーをどのように宣言するかについては以下を確認してください。

https://github.com/rails/strong_parameters#nested-parameters

Deviseのモデルが複数ある場合は、モデルごとに異なるパラメタに対するサニタイザを設定したくなると思います。この場合は、Devise::ParameterSanitizerを継承した上で、ロジックを追加することを進めます。

class User::ParameterSanitizer < Devise::ParameterSanitizer

def sign_in
default_params.permit(:username, :email)
end
end

その上で、コントローラの中で利用してください。

class ApplicationController < ActionController::Base

protected

def devise_parameter_sanitizer
if resource_class == User
User::ParameterSanitizer.new(User, :user, params)
else
super # Use the default one
end
end
end

上記の例では、userの:username:emailの両方に適用されるようpermitted parametersをオーバライドしています。まじめにやろうとすると、カスタムコントローラで、beforeフィルタを定義することによりパラメータを設定することになります。以降のセクションで、コントローラを設定し、カスタマイズする方法の詳細を説明します。


Configuring views

ここまでは、認証を利用するアプリケーションを簡単に開発するためDeviseを利用しました。しかし、カスタマイズする必要がある場合もある。

Deviseはエンジンであるため、gemの中にビューが全てパッケージされている。これらのビューは始めたばかりの時には役立ちますが、作業をしているうちに変更したくなります。こうした場合は、次のようにgeneratorを呼び出して、アプリケーションにすべてのビューをコピーしてください。

rails genrate devise:views

アプリケーション内に複数のモデル(UserAdminなど)がある場合は、Deviseがすべてのモデルで同じビューを利用することを念頭においてください。幸運なことに、Deviseではビューを簡単にカスタマイズすることができます。config/initializers/devise.rbファイルにconfig.scoped_views = trueをセットするだけです。

そうしたら、users/sessions/newadmins/sessions/newのようにロールごとにビューを持つことができます。ビューが適切な場所に存在しない場合は、Deviseは、devise/sessions/newというデフォルトビューを利用します。モデルごとのビューを作りたい場合は、以下のようにします。

rails generate devise:views users

registerableconfrimableモジュールだけ」というような、ビューのうちいくつかだけを生成したい場合は、-vフラグでモジュールのリストをgeneratorに渡します。

rails generate devise:views -v registrations confirmations


Configuring controllers

ビューのカスタマイズだけでは足りない場合、以下のステップで、ビューをカスタマイズすることができます。


  1. スコープをgeneratorに渡して、コントローラを作成します

   rails generate devise:controllers [scope]

スコープとしてusersを使いたい場合、コントローラはapp/controllers/user/に作成されます。セッションコントローラは以下のような感じです。

   class Users::SessionsController < Devise::SessionsController

# GET /resource/sign_in
# def new
# super
# end
...
end


  1. コントローラを利用するためのルーティング設定をします

   devise_for :users, controllers: { sessions: "users/sessions" }


  1. devise/sessions/からusers/sessionsにビューをコピーします。コントローラがへ高されたので、devise/sessionsにあるデフォルトビューは使われません。



  2. 最後に、コントローラ上でアクションを変更もしくは拡張します。

    コントローラのアクションを完全にオーバライドすることもできます。

     class Users::SessionsController < Devise::SessionsController
    
    def create
    # custom sign-in code
    end
    end

    もしくは単に新しい振る舞いを追加することもできます。

     class Users::SessionsController < Devise::SessionsController
    
    def create
    super do |resource|
    BackgroundWorker.trigger(resource)
    end
    end
    end

    上記のコードはバックグラウンドジョブのトリガーや、特定のアクション中のロギングイベントに有効です。



Deviseは、サインインの成功や失敗を伝えるのにflashメッセージを利用します。Deviseでは、アプリケーション内でflash[:notice]flash[:alert]を適切に利用してください。flashハッシュのすべてを表示するのではなく、特定のキーを表示してください。特定の環境においては、Deviseは:timeoutキーをflashハッシュとして追加しますが、表示にはテキしていません。もしハッシュをそのまま表示するつもりなら、このキーは削除してください。


Configuring routes

Deviseは、デフォルトでルーティングを設定します。カスタマイズする必要があれば、devise_forメソッドを使ってカスタマイズしてもよいでしょう。以下のようにi18n対応のパスを許可するものを含め、:class_nameや:path_prefixなどのオプションがあります。

devise_for :users, path: "auth", path_names: { sign_in: 'login', sign_out: 'logout', password: 'secret', confirmation: 'verification', unlock: 'unblock', registration: 'register', sign_up: 'cmon_let_me_in' }

詳細はdevise_forのデモを確認してください。

例えば"/users/sign_in"に加え"/sign_in"を許可したいなど、さらなるカスタマイズが必要な場合は、通常通りルーティングの設定を行い、devise_scopeブロックで囲うだけでOKです。

devise_scope :user do

get "sign_in", to: "devise/sessions#new"
end

このように設定すると、"/sign_in"にアクセスがあると、Deviseは:userスコープを利用します。devise_scopeはルーティング設定内ではasとしてもエイリアスされています。


I18n

Deviseは、:noticeや:alertというフラッシュキーで接続された、I18nのflashメッセージを利用します。アプリケーションをカスタマイズするためには、localeファイルを設定してください。

en:

devise:
sessions:
signed_in:
'Signed in successfully.'

ルーティング設定内で特定可能な名前を利用することで、リソースごとに異なるメッセージを作成することもできます。

en:

devise:
sessions:
user:
signed_in:
'Welcome user, you are signed in.'
admin:
signed_in:
'Hello admin!'

Deviseのメーラは、件名を同様にして独立して定義されたものを利用します。

en:

devise:
mailer:
confirmation_instructions:
subject:
'Hello everybody!'
user_subject: 'Hello User! Please confirm your email'
reset_password_instructions:
subject:
'Reset instructions'

利用可能なメッセージについては、以下のlocaleファイルをご覧ください。wikiにある翻訳も利用可能です。

https://github.com/plataformatec/devise/wiki/I18n

注意: Devise Controllersは、ApplicationControllerを継承しています。アプリ内で複数のlocaleを利用する場合は、ApplicationControllerでI18n.localeを設定しなくてはなりません。


Test helpers

Deviseはspec用にtest helperを含んでいます。利用するには、test/test_helper.rbファイルの最後に以下のコードを追加します。

class ActionController::TestCase

include Devise::TestHelpers
end

RSpecを利用しているのであれば、spec/support/devise.rbspec/spec_helper.rb(もしくは、rspec-railsを利用しているのであればspec/rails_helper.rb)というファイルに以下のコードを埋めてください。

RSpec.configure do |config|

config.include Devise::TestHelpers, type: :controller
end

require 'rspec/rails'ディレクティブの後で有効であることに気をつけてください。

これで、sign_insign_outメソッドが利用できる準備が整いました。これらのメソッドはコントローラ内で利用可能です。

sign_in :user, @user   # sign_in(scope, resource)

sign_in @user # sign_in(resource)

sign_out :user # sign_out(scope)
sign_out @user # sign_out(resource)

覚えておくべきことがふたつあります。


  1. これらのhelperは、CapybaraやWebratによる結合試験では利用できません。機能試験のみで利用できます。フォームへ入力するかセッションにユーザをセットしてください。

  2. Deviseの内部コントローラやDevise自体を継承したコントローラを試験する場合は、リクエストの前にどのマッピングが使われるかをDeviseに知らせる必要があります。これはDeviseがルータからこの情報を得るためですが、機能テストはルータを通さないので明確にする必要があります。例えば、userスコープをテストする場合は、シンプルに以下のように記載します。

@request.env["devise.mapping"] = Devise.mappings[:user]

get :new

RSpecでのRails3、Rails4のコントローラの試験については、以下のwikiで詳細を確認してください。


OmniAuth

Deviseは、すぐに様々な認証を利用できるOmniAuthをサポートしています。利用するには、OmniAuthの設定をconfig/initializers/devise.rbに記載します。

config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo'

wikiにさらに詳細な情報があります。


Configuring multiple models

Deviseは好きなだけモデルをセットアップできます。上記のUserモデルに加え、認証にタイムアウト機能を備えただけのAdminモデルを作りたい場合は、以下のようにします。

# Create a migration with the required fields

create_table :admins do |t|
t.string :email
t.string :encrypted_password
t.timestamps null: false
end

# Inside your Admin model
devise :database_authenticatable, :timeoutable

# Inside your routes
devise_for :admins

# Inside your protected controller
before_filter :authenticate_admin!

# Inside your controllers and views
admin_signed_in?
current_admin
admin_session

あるいは、Devise generatorを呼ぶ出すだけでも可能です。

これらのモデルは完全に異なるルーティングになることを注意してください。サインイン、サインアウトなどについて、コントローラを共有することは ありませんしできません 。同じアクションを異なるロールで共有したい場合は、ロールのカラムを使うか、それに特化したgemを利用するというようなロールベースのアプローチをお勧めします。


ActiveJob Integration

バックエンドでのキューイング用にActionMailerのメッセージ配信をするために、Rail4.2とActiveJobを利用している場合は、モデル内でsend_devise_notificationメソッドをオーバーライドすることにより既存のキューを通してDeviseのメールを送信することができます。

def send_devise_notification(notification, *args)

devise_mailer.send(notification, self, *args).deliver_later
end


Password reset tokens and Rails logs

Recoverableモジュールを有効にする場合は、パスワードリセットのトークンが盗まれると、攻撃者がアプリケーションにアクセスできてしまうことに注意してください。Deviseは、ランダムでセキュアなトークンを生成し、データベースにトークンのdigestのみを保存します。これは平文ではありません。しかしながら、Railsにおけるデフォルトのロギングでは、ログファイルに平文のtokenを漏らしてしまいます。


  1. Action MailerはDEBUGレベルにて、送付メールのすべてのコンテンツをログに出力します。ユーザに送付されたパスワードリセットのトークンが漏れることになります。

  2. Active JobはINFOレベルにて、各キューに対する全ての引数をログに出力します。パスワードリセットのメールを送付するためにdeliver_laterをDeviseで設定した場合、パスワードリセットのトークンが漏れることになります。

RailsはデフォルトでproductionのログレベルをDEBUGに設定します。ログにトークンが出力されないようにしたいのであれば、productionのログレベルをWARNに変更してください。config/environments/production.rb内で以下のように設定します。

config.log_level = :warn


Other ORMs

Deviseは、ActiveRecord(デフォルト)とMongoidをサポートしています。他のORMを利用するためには、initializerファイルでrequireしてください。


Additional information


Heroku

Ruby on Rails 3.2のHeroku上でDeviseを使うには、以下のように設定します。

config.assets.initialize_on_precompile = false

その他の潜在的な問題については、http://guides.rubyonrails.org/asset_pipeline.html で紹介されています。


Warden

DeviseはWardenをベースにしています。Wardenは、Daniel Neighmanによって構築されたRackベースの認証フレームワークです。Wardenについては以下が参考になります。

https://github.com/hassox/warden


Contributors

DeviseにはたくさんのContributorがいます。以下に全員記載してます。

https://github.com/plataformatec/devise/graphs/contributors


Lisence

MIT License. Copyright 2009-2015 Plataformatec. http://plataformatec.com.br

You are not granted rights or licenses to the trademarks of Plataformatec, including without limitation the Devise name or logo.