deviseを使ってログイン機能実装


20181001
## やったこと
- booksアプリにdeviseでログイン機能を実装

参考[How To: Allow users to sign in using their username or email address · plataformatec/devise Wiki · GitHub](https://github.com/plataformatec/devise/wiki/How-To:-Allow-users-to-sign-in-using-their-username-or-email-address)

## 手順
### gemfile
```ruby
gem 'devise' # 最初deviceって書き間違い、地味にハマる。。
```
### setup
```shell
rails g devise:install
```
### devisemodel生成
```shell
$ rails g devise user
```
## ヘルパーメソッド
-  before_action :authenticate_user！
ログイン済みユーザーにアクセス許可 
- user_signed_in？
ユーザーのログイン有無をboolean値で返すメソッド=>ログインの有無でページ表示分岐
- current_user
ログイン中のユーザー自身の情報

## 独自パラメータの追加
- deviseのストロングパラメータ設定には、configure_permitted_parametersメソッドを使う
- deviseのコントローラはgem本体にあるため、ストロングパラメータはapplication_controllerに設定する

### nameパラメータ追加例
```ruby
class ApplicationController < ActionController::Base
  def configure_permitted_parameters
    added_attrs = [:name, :email, :password, :password_confirmation, :remember_me]
    devise_parameter_sanitizer.permit :sign_up, keys: added_attrs
    devise_parameter_sanitizer.permit :account_update, keys: added_attrs
  end
end
```
### nameパラメータのレコード登録例
```shell
Started POST "/users" for 127.0.0.1 at 2018-09-27 22:58:49 +0900
Processing by Devise::RegistrationsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"41ZyE8Vcq2lL4YZO1q1XQh5qN1CDOyJq8ORah2qdKWJ6ofkQWx97BjGyBdZYwozHzQmcZNTjb16W0P/o6hgwmw==", "user"=>{"name"=>"abe", "email"=>"abe@gmail.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Sign up"}
   (0.1ms)  begin transaction
  ↳ /Users/kuriharayasuaki/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activerecord-5.2.1/lib/active_record/log_subscriber.rb:98
  User Exists (0.2ms)  SELECT  1 AS one FROM "users" WHERE "users"."email" = ? LIMIT ?  [["email", "abe@gmail.com"], ["LIMIT", 1]]
  ↳ /Users/kuriharayasuaki/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activerecord-5.2.1/lib/active_record/log_subscriber.rb:98
  User Create (0.5ms)  INSERT INTO "users" ("name", "email", "encrypted_password", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?)  [["name", "abe"], ["email", "abe@gmail.com"], ["encrypted_password", "$2a$11$AM0CgRsv.CLTIpWNwNDKZOpE2hXpzMbAdHbqqnnxvs6pz.iEodhT2"], ["created_at", "2018-09-27 13:58:49.601612"], ["updated_at", "2018-09-27 13:58:49.601612"]]
  ↳ /Users/kuriharayasuaki/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activerecord-5.2.1/lib/active_record/log_subscriber.rb:98
   (1.4ms)  commit transaction
  ↳ /Users/kuriharayasuaki/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activerecord-5.2.1/lib/active_record/log_subscriber.rb:98
Redirected to http://localhost:3000/
Completed 302 Found in 159ms (ActiveRecord: 2.2ms)
```

## モデルが扱うdeviseの機能
```ruby
# 例
class User < ApplicationRecord
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable
end
```
### デフォルトモジュール
- ### database_authenticatable
ログイン時のパスワードを暗号化してデータベースに保存する機能。

- ### registerable
新規登録（サインアップ）処理を実行する。アカウントの編集・削除も許可。

- ### recoverable
パスワードリセット機能。

- ### rememberable
cookieにユーザー情報を持たせる。

- ### trackable
サインインした回数や時刻、IPアドレスを記録する。

- ### validatable
デフォルトでメールアドレスとパスワードのバリデーションを提供。
カスタマイズすることで、他の組み合わせ（ユーザー名とパスワード）も可能。

### 追加可能機能

- ### lockable
サインインに一定回数失敗するとアカウントをロックさせる機能。

- ### confirmable
新規登録（サインアップ）時に確認メールを送り、その中にあるURLをクリックすることで正式登録とする機能。

- ### timeoutable
一定時間使われていないセッション情報を削除する機能。

- ### omniauthable
OmniAuthサポートする。SNSログインには必須。

## 所感
sorceryと比べると、ルーティングやパラメータ、モデルを任意に弄りたい場合面倒な印象を受けた。