Deviseの使い方

[公式](https://github.com/plataformatec/devise)に書かれていることを、端折って日本語で書いただけです。

調べたことの備忘録なので、不定期で更新される可能性があります。
間違っている点や、怪しい日本語訳があると思いますorz

# 環境
Ruby: 2.2.1
Rails: 4.2.3
devise: 3.5.1

# Devise
## インストール
```
$ bundle exec rails g devise:install
      create  config/initializers/devise.rb
      create  config/locales/devise.en.yml
```

## 初期設定
インストール完了後のメッセージに表示されますが、以下の設定を行う。

```
# environmentごとにURL情報を設定
# ex) config/environments/development.rb
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
```

### モデル作成
```
# ここでは「User」モデルを作ることとします。
$ bundle exec rails g devise User
      invoke  active_record
      create    db/migrate/20150710020211_devise_create_users.rb
      create    app/models/user.rb
      insert    app/models/user.rb
       route  devise_for :users
```

## 使い方
`User`モデルを前提で記述します。
もし、異なる名称のモデルにした場合は、`user`部分を置き換えてください。
※動的メソッド

### 認証チェック
認証を必要とするコントローラに、以下を追記。

```
# 認証されていない場合は、ログイン画面にリダイレクトされます。
before_action :authenticate_user!
```

### アカウント情報
ログインしているアカウントの情報は、以下で取得できます。

```
current_user
```


## 任意の設定
### モデル
deviseのオプションを選択します。
オプションは10個のクラスに分かれており、シンボルで指定します。

```
# app/models/user.rb
class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable
end
```

#### オプション
##### Database Authenticatable
パスワード認証機能。

ログインするときに、DBに暗号化して登録されたパスワードを使って認証を行う。
認証処理は、POSTリクエスト／BASIC認証を通して行われます。

```
# 該当カラム
t.string :email,              null: false, default: ""
t.string :encrypted_password, null: false, default: ""
```

##### Omniauthable
OAuthをサポート。
※[OmniAuth](https://github.com/intridea/omniauth)を利用。

##### Confirmable
登録確認機能。

アカウント登録時に確認メールを送信し、ログイン時に確認されているかをチェックする。

```
# 該当カラム
t.string   :confirmation_token
t.datetime :confirmed_at
t.datetime :confirmation_sent_at
t.string   :unconfirmed_email # Only if using reconfirmable
```

##### Recoverable
パスワードリセット機能

パスワードを紛失した際に、パスワードのリセットを行うことができます。
リセット時にメールを送信し、パスワードの再設定を行う。

```
# 該当カラム
t.string   :reset_password_token
t.datetime :reset_password_sent_at
```

##### Registerable
アカウント操作機能

アカウントの登録／削除と、各ユーザが自分自身の編集をすることができます。

##### Rememberable
ログイン情報の保持機能

クッキーを利用して、ログイン情報の保持を行うことができます。
※クッキーが有効な期間は、ログイン情報を入力せずにログインが可能。

```
# 該当カラム
t.datetime :remember_created_at
```

##### Trackable
ログイン情報の登録

ログイン時に、ログイン回数／ログイン時間／IPアドレスをDBに登録されます。

```
# 該当カラム
t.integer  :sign_in_count, default: 0, null: false
t.datetime :current_sign_in_at
t.datetime :last_sign_in_at
t.string   :current_sign_in_ip
t.string   :last_sign_in_ip
```

##### Timeoutable
強制ログアウト機能

一定時間、画面操作が行われなかった時に、ログアウトさせることができます。

##### Validatable
認証機能

Eメールとパスワードの組み合わせで認証することができます。
認証方法を変えたい場合は、独自で定義を行うことができます。

##### Lockable
アカウントロック機能

一定回数ログインに失敗した時に、アカウントをロックさせることができます。
一定時間経過するか、Eメールに記載されている解除URLからロックを解除することができます。

```
# 該当カラム
t.integer  :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts
t.string   :unlock_token # Only if unlock strategy is :email or :both
t.datetime :locked_at
```

### ビュー
カラムを追加したり、デザインを変えたりする場合は、テンプレートのビューを`app/views/devise`配下に作成。

```
$ bundle exec rails g devise:views
      invoke  Devise::Generators::SharedViewsGenerator
      create    app/views/devise/shared
      create    app/views/devise/shared/_links.html.erb
      invoke  form_for
      create    app/views/devise/confirmations
      create    app/views/devise/confirmations/new.html.erb
      create    app/views/devise/passwords
      create    app/views/devise/passwords/edit.html.erb
      create    app/views/devise/passwords/new.html.erb
      create    app/views/devise/registrations
      create    app/views/devise/registrations/edit.html.erb
      create    app/views/devise/registrations/new.html.erb
      create    app/views/devise/sessions
      create    app/views/devise/sessions/new.html.erb
      create    app/views/devise/unlocks
      create    app/views/devise/unlocks/new.html.erb
      invoke  erb
      create    app/views/devise/mailer
      create    app/views/devise/mailer/confirmation_instructions.html.erb
      create    app/views/devise/mailer/reset_password_instructions.html.erb
      create    app/views/devise/mailer/unlock_instructions.html.erb
```

### コントローラ
デフォルトの処理から変更したい場合は、deviseのコントローラをoverrideする。

```
# 「user」モデルなので、引数に`users`を指定しています。
$ bundle exec rails g devise:controllers users
      create  app/controllers/users/confirmations_controller.rb
      create  app/controllers/users/passwords_controller.rb
      create  app/controllers/users/registrations_controller.rb
      create  app/controllers/users/sessions_controller.rb
      create  app/controllers/users/unlocks_controller.rb
      create  app/controllers/users/omniauth_callbacks_controller.rb
```

generate完了後のメッセージに表示されますが、以下の設定を行います。

```
# routes.rb
# overrideするコントローラを指定
devise_for :users, controllers: {
  confirmations: 'users/confirmations',
  passwords: 'users/passwords',
  registrations: 'users/registrations',
  sessions: 'users/sessions',
  unlocks: 'users/unlocks',
  omniauth_callbacks: 'users/omniauth_callbacks'
}
```

#### 追加カラム
Strong Parameterを有効にしていて追加カラムがある場合は、permitの設定をする必要があります。

```
class ApplicationController < ActionController::Base
  before_action :configure_permitted_parameters, if: :devise_controller?

  protected

  def configure_permitted_parameters
    # アカウント登録時に「username」を追加した場合
    devise_parameter_sanitizer.for(:sign_up) << :username
  end
end
```

`for()`で指定できるシンボルは、以下の3点です。

- `:sign_in`: ログイン時
- `:sign_up`: アカウント登録時
- `:account_update`: アカウント更新時