【Rails】deviseの使用方法

#deviseとは
webアプリに安全な認証(アクセスしたユーザーの正当性を確認する)処理を簡単に
実装出来るgem(ライブラリ)。

主な機能(その他、カスタマイズ可)
・ユーザーの登録処理
・ユーザーの仮登録(本登録のためのメール送付)
・ログイン処理
・認証機能(ログイン済か確認)
・パスワードの変更
・パスワードの再発行
・認証関連の各種画面

#deviseの導入

PCに標準搭載させていないので、インストールが必要。
事前に、動作確認用のアプリを用意しておく。

#インストール
アプリのGemfileに以下の1文を追加する。

```ruby:Gemfile
gem 'devise'
```

アプリのフォルダ内で、以下のコマンドを入力し、deviseをインストールする。

```
$ bundle install
```

deviseのインストール完了後の確認方法
↓
「Gemfile.lock」ファイル内に「devise」の記載があればOK。

#deviseの設定
アプリへ組み込むため、以下のコマンドを実行。

```
$ rails g devise:install
```
↑
※gはgenerateコマンドの略称

このコマンドで、deviseの実行に必要なファイルを生成する。しかし、まだdeviseの機能を使うことはできない。コマンドを実行した際に表示される。
以下のメッセージに従って、初期設定を行う。

```
Some setup you must do manually if you haven't yet:
 
  1. Ensure you have defined default url options in your environments files. Here
     is an example of default_url_options appropriate for a development environment
     in config/environments/development.rb:
 
       config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
 
     In production, :host should be set to the actual host of your application.
 
  2. Ensure you have defined root_url to *something* in your config/routes.rb.
     For example:
 
       root to: "home#index"
 
  3. Ensure you have flash messages in app/views/layouts/application.html.erb.
     For example:
 
       <p class="notice"><%= notice %></p>
       <p class="alert"><%= alert %></p>
 
  4. You can copy Devise views (for customization) to your app by running:
 
       rails g devise:views
```

上記の内容を訳すと
1．deviseがメール送付する場合の送付元（WebアプリURL）の指定
2．ログアウト時のリダイレクト（転送）先URLの指定
3．ログインやログアウトなどの処理結果を表示するメッセージ領域の作成
4．deviseで使用する表示画面用テンプレートの作成（作成しなくても良いが、カスタマイズする場合は作成する必要がある）

1から４に対してそれぞれ設定していく。

#1. メール送付元URLの設定

```rails:config/environments/development.rb
Rails.application.configure do
    :
   省略
    :
  config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }  # この行を追加
    :
end
```

- hostとportを、WebアプリへアクセスするときのURLに合わせる。
- hostとportを分けずに「{ host:'localhost:3000' }」という記載方法法でもOK。

#2. リダイレクト先URLの設定
ログインしていない場合、リダイレクト先URLを設定。つまり、1.で設定したURLに最初にアクセスしたときに表示される画面のURLを設定する。

この設定がなければ、ログインしていない場合やログアウト後の遷移先がないので、エラー表示になる。

※例として、以下のコマンドでAccessesコントローラーとhelloアクション、goodbyeアクションを生成。

```
$ rails g controller Accesses hello goodbye
```

```config/routes.rb
Rails.application.routes.draw do
       :
  root 'accesses#hello' #(root設定がなければ)この行を追加
       :
end
```

#3. メッセージ領域の作成
ログインやログアウトの操作をした結果をユーザーへメッセージを表示してくれる。表示領域は、Webアプリ制作者が任意の場所を設定できるようになっている。（設定しなければ、表示さされない）

例として、以下の2行をbodyタグに追記。

```app/views/layouts/application.html.erb

           :
          省略
           :

 <body>
   <p class="notice"><%= notice %></p>
   <p class="alert"><%= alert %></p>

   <%= yield %>

 </body>
<html>
```

#4. devise用のviewの作成(任意)
Webアプリのテイストに合わせてカスタマイズしたい場合、devise用のviewファイルを生成して変更できるようにすることも可能。
devise用のviewファイルを確認するため、以下のコマンドを使ってviewを生成する。

```
$ rails g devise:views
```

これで、初期設定は完了。
以後、ユーザー情報を登録する準備や必要な機能を有効にする。

#ユーザーモデルを生成
認証処理を行うためには、ユーザー情報の登録が必要。そのため、ユーザー情報を登録するためのテーブルを、データベース上に作る必要がある。
また、そのテーブルへのデータ登録や変更、削除、認証処理を行うメソッドなどを利用するためのモデルを生成する

##ユーザーのマイグレーションとモデルを生成


deviseであれば、以下のコマンド1行で済む。

```
$ rails g devise モデル名
```

※モデル名は例として、hello_userとする。
※モデル名は必ず小文字単数形を使用。

生成されたファイル(2つ)

```db/migrate/20190605054642_devise_create_hello_users.rb
# frozen_string_literal: true

class DeviseCreateHelloUsers < ActiveRecord::Migration[5.2]
  def change
    create_table :hello_users do |t|
      ## Database authenticatable
      t.string :email,              null: false, default: ""
      t.string :encrypted_password, null: false, default: ""
              :
              :
              :
end
```
```app/models/hello_user.rb
class HelloUser < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable
end
```
↑
ユーザー認証機能を実現するモデルファイル

上記で定義されている「database_authenticatable」「registerable」「recoverable」「rememberable」「validatable」が、標準機能。
※計10個のファイルがある。追加、削除可能。

##テーブルの作成
テーブルを生成するコマンドを実行。

```
rails db:migrate
```
で、完了。

あとはユーザー登録やログイン、ログアウトできるようにリンクを配置することで、実装完了。

以下、修正。

```app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
  <head>
    <title>SampleDevise</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
  </head>

  <body>
    <header>
        <nav>
        <% if hello_user_signed_in? %>
            <strong><%= link_to current_hello_user.username, pages_show_path %></strong>
            <%= link_to 'edit profile', edit_hello_user_registration_path %>
            <%= link_to 'logout', destroy_hello_user_session_path, method: :delete %>
        <% else %>
            <%= link_to 'registration', new_hello_user_registration_path %>
            <%= link_to 'login', new_hello_user_session_path %>
            <% end %>
        </nav>        
    </header>

    <p class="notice"><%= notice %></p>
    <p class="alert"><%= alert %></p>

    <%= yield %>
  </body>
</html>
```

hello_user_signed_in?メソッドを使ってユーザーがログイン状態かどうかを判定し、ログイン状態であれば、「edit profile」と「logout」のリンク、ログインしていなければ、「registration」と「login」のリンクを表示。

##動作確認

ローカル環境の場合は、「http://localhost:3000/」
実際に必要な情報を入力してユーザー登録したり、ログイン、ログアウトしてみて、動作確認する。



###参考サイト
https://web-camp.io/magazine/archives/16811