Rails入門4: deviseでユーザー認証してみよう
#01:ユーザー認証機能を理解しよう
このレッスンでは、Railsのユーザー認証用ライブラリdeviseを使って、Webアプリケーションで必要になるユーザー認証の基本を学習します。
まず初めに、ユーザー認証の概要と、deviseの役割を理解しましょう。
ユーザー認証とは
相手を確認してアクセスを許可する仕組みを「ユーザー認証」と呼びます。
ユーザー認証
- 認証:Authentication 本人かどうか確認する
- 許可:Authorization 認証の結果をあたえ、利用許可
deviseの主な機能
deviseは、ユーザー認証の仕組みをRailsに提供するライブラリです。
- サインアップ:ユーザー情報と暗号化したパスワードをデータベースに保存
- メールによるユーザー確認
- ログイン:メールとパスワードによる認証
- クッキーによるセッション管理
- ユーザー追跡:ログイン回数、日時、IPアドレスなど
- パスワードリセット
- ユーザーのロック
- OmniAuth対応:TwitterやFacebookなどによるSNS認証
参考になるWebページ
- [ASCII.jp:ユーザー認証でなにができるのですか?|セキュリティの素朴な疑問を解く]
http://ascii.jp/elem/000/000/436/436614/
[よくわかる認証と認可 | Developers.IO]
https://dev.classmethod.jp/security/authentication-and-authorization/[【プログラマ英語】それ認証って意味じゃないですよ(厳密には) - Qiita]
https://qiita.com/tienlen/items/9e1b58dd173472f071c0[plataformatec/devise]
https://github.com/plataformatec/devise[Railsのログイン認証gemのDeviseのインストール方法 - Rails Webook]
http://ruby-rails.hatenadiary.com/entry/20140801/1406907000
#02:ログインフォームの動作確認
ここでは、deviseで作ったログインフォームを実際に使ってみましょう。deviseでは、ユーザー認証のために多くの機能を提供します。
ログイン情報
Email: kirishima@paiza.jp
パスワード: password
deviseの主な機能
deviseは、ユーザー認証の仕組みをRailsに提供するライブラリです。
- サインアップ:ユーザー情報と暗号化したパスワードをデータベースに保存
- メールによるユーザー確認
- ログイン:メールとパスワードによる認証
- クッキーによるセッション管理
- ユーザー追跡:ログイン回数、日時、IPアドレスなど
- パスワードリセット
- ユーザーのロック
- OmniAuth対応:TwitterやFacebookなどによるSNS認証
#03:deviseを導入する
ここでは、Ruby on Railsに、deviseを導入します。そして、いくつかの基本設定で、deviseを使えるようにします。
プロジェクトと静的ページの作成
$ rails new bbs_users
$ cd bbs_users
$ rails g controller welcome index
動画0:50でエラーが出る場合
rails g controller welcome index でエラーが出る場合、bbs_users/db/Gemfileの12行目でバージョンを指定する
gem 'sqlite3', '~> 1.3.6'
Railsを始めてsqlite3まわりのエラーで躓いている人たちへ
https://qiita.com/Kta-M/items/254a1ba141827a989cb7
deviseライブラリを追加してインストールする
Gemfile
gem 'devise'
$ bundle install
$ rails g devise:install
手動設定1.デフォルトURLを追加する
config/environments/development.rb
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
config.action_mailer.raise_delivery_errors = false
config.action_mailer.perform_caching = false
手動設定2.root_urlを指定する
config/routes.rb
root 'welcome#index'
手動設定3.フラッシュメッセージの表示場所を作る
app/views/layouts/application.html.erb
<%= notice %>
<%= alert %>
<%= yield %>
手動設定4.ユーザー認証用のviewを生成する
$ rails g devise:views
deviseのViewの対応
- ログイン: app/views/devise/sessions/new.html.erb
- サインアップ: app/views/devise/registrations/new.html.erb
- ユーザ情報変更: app/views/devise/registrations/edit.html.erb
- パスワード変更: app/views/devise/passwords/edit.html.erb
- メール認証: app/views/devise/confirmations/new.html.erb
- パスワードリセット: app/views/devise/passwords/new.html.erb
- アカウントアンロック: app/views/devise/unlocks/new.html.erb
演習課題「deviseをインストールする」
右の環境には、「myblog」プロジェクトに「Welcome#index」という静的ページが作成してあります。
すでに、deviseのgemが導入してあります。
ここで、deviseのインストールを実行してください。なお、手動設定は全て不要です。
採点して、すべてのジャッジに正解すれば、演習課題クリアです!
模範解答1
次のコマンドをターミナルで実行する
rails g devise:install
#04:ユーザー認証用のUserモデルを作成
ここでは、ユーザー認証のためにUserモデルを作成します。そして、できあがったログイン画面を呼び出してみましょう。
Userモデルを作成する
$ rails g devise User
$ rails db:migrate
Deviseに初期ユーザを一括登録
db/seeds.rb
User.create(email: 'admin@paiza.jp', password: 'password')
User.create(email: 'kirishima@paiza.jp', password: 'password')
User.create(email: 'neko@paiza.jp', password: 'password')
$ cd bbs_users
$ rails db:seed
ユーザー認証
サインアップ
https://xxxx.paiza-app:3000/users/sign_up
ログイン
https://xxxx.paiza-app:3000/users/sign_in
演習課題「管理者ログインを作成する」
右の環境には、「myblog」プロジェクトに「Welcome#index」という静的ページが作成してあります。また、ユーザー認証構築用にdeviseが導入済みです。
ここに、deviseを使って「Admin」というモデルを作成してください。
また、マイグレーションも実行してください。
採点して、すべてのジャッジに正解すれば、演習課題クリアです!
模範解答1
次のコマンドを順にターミナルで実行する
rails g devise Admin
rails db:migrate
#05:アクセスを制限する
ここでは、deviseで作成したユーザー認証機能にログアウト機能を追加します。また、ログインしている時だけ、Welcomeページを表示できるようにアクセス制御します。
ログインナビゲーションを追加
app/views/welcome/index.html.erb
<% if user_signed_in? %>
Logged in as <%= current_user.email %>.
<%= link_to "Settings", edit_user_registration_path %> |
<%= link_to "Logout", destroy_user_session_path, method: :delete %>
<% end %>
この時、ヘルパーメソッドの「user」の部分は、モデル名の「User」に合わせて記述しています。
ログインページに強制移動
app/controllers/welcome_controller.rb
class WelcomeController < ApplicationController
before_action :authenticate_user!
def index
end
end
参考になるWebページ
- [ログイン認証も簡単!Railsでのdeviseの使い方 | TechAcademyマガジン]
https://techacademy.jp/magazine/7336
- [STEP21:Rails5にdeviseでログイン機能を実装しよう! #Rails #Ruby | TickleCode]
http://ticklecode.com/devise/
- [Devise に初期ユーザを追加 - Ruby and Rails]
http://rubyandrails.hatenablog.com/entry/devise-user-create
- [RailsのDBの初期データ(rake db:seed用)をyamlで美しく管理する方法 - Qiita]
https://qiita.com/yukimura1227/items/ff04eb6a771ffe1ab0b8
- [【Rails入門】seedの使い方まとめ | 侍エンジニア塾ブログ | プログラミング入門者向け学習情報サイト]
https://www.sejuku.net/blog/28395
演習課題「管理者ログインに初期ユーザーを登録する作成する」
右の環境には、「myblog」プロジェクトに「Welcome#index」という静的ページが作成してあります。
また、ユーザー認証構築用にdeviseを導入して、「Admin」というモデルを作成してあります。
ここに、以下の初期ユーザーを登録してください。この時、seed.rbファイルで一括登録します。
- email: 'admin@paiza.jp', password: 'password'
模範解答1
/home/ubuntu/myblog/db/seed.rbファイルに登録するデータを記述する。
Admin.create(email: 'admin@paiza.jp', password: 'password')
模範解答2
次のコマンドを順にターミナルで実行する
rails db:seed
演習課題「間違い探し:管理者ログインのナビゲーションを作成する」
右の環境には、「myblog」プロジェクトに「Welcome#index」という静的ページが作成してあります。
また、ユーザー認証構築用にdeviseを導入して、「Admin」というモデルを作成してあります。
ここに、全てのページにナビゲーションを表示するようコードを記述してありますが、エラーになってしまいます。
間違いを修正して、正常に表示されるようにしてください。
模範解答1
/home/ubuntu/myblog/app/views/layouts/application.html.erbに記述する。
ヘルパーメソッドは、すべてモデル名のAdminに合わせる。
<!DOCTYPE html>
Myblog
<%= csrf_meta_tags %>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
<% if admin_signed_in? %>
演習課題「ログインしていないと強制移動」
右の環境には、「myblog」プロジェクトに「Welcome#index」という静的ページが作成してあります。また、ユーザー認証構築用にdeviseを導入して、「Admin」というモデルを作成してあります。
この時、ログインしていないとログインページに強制移動するよう、Welcome#indexページを設定してください。
採点して、すべてのジャッジに正解すれば、演習課題クリアです!
模範解答1
/home/ubuntu/myblog/app/controllers/welcome_controller.rbに、
before_actionを記述する。
ヘルパーメソッドは、モデル名の「Admin」に合わせて記述する。
class WelcomeController < ApplicationController
before_action :authenticate_admin!
def index
end
end
#06:セッションとパスワードを理解する
ここでは、ログイン状態を保持するセッションとユーザーを認証するパスワードについて学習します。deviseを使うと、セッション管理機能も簡単に組み込むことができます。
セッションとは
ログインしてから、ログアウトするまでの一連のアクセスを「セッション」と呼びます。
Webサイトへの基本的なアクセスでは、アプリケーション側でそれぞれのアクセスは独立しています。そのために、同じ人が同じサイトに複数回アクセスしても、それぞれのアクセスを区別できません。これでは、アクセスするたびにログインし直す必要があります。
そこで、セッションという仕組みが使われています。セッションは、ログインすると開始して、そのアクセスを区別する「セッション情報」を記録します。そして、ログアウトしたり、ブラウザを閉じて一定時間が経ったりすると終了します。この「セッション情報」おかげで、セッションが有効な間、Webアプリケーションに同じ人がアクセスしていると判断できるようになります。
セッションを確認する手順
Google Chromeの場合
1.「設定」メニューを呼び出す
2.「詳細設定」-「コンテンツの設定」-「Coookies」-「すべてのクッキーとサイトデータ」
3.Webアプリケーションのドメイン名を検索する
暗号化されたパスワードの確認手順
$ rails console
user = User.find(2)
user.email
user.encrypted_password
参考になるWebページ
- [セッション (session)とは|「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典]
http://wa3.i-3-i.info/word1791.html
[今さら聞けないセッションとCookie、ログイン・ログアウト(Rails編) - Qiita]
https://qiita.com/SpicyCoffee/items/de9de9a5427adf81817a[Rails4での基本的なセッションの使い方 - Rails Webook]
http://ruby-rails.hatenadiary.com/entry/20141130/1417334030[Rails セキュリティガイド | Rails ガイド]
https://railsguides.jp/security.html[第8章 ログイン、ログアウト | Rails チュートリアル]
https://railstutorial.jp/chapters/log_in_log_out?version=4.2#cha-log_in_log_out
演習課題「セッションidを削除する」
右の環境には、「myblog」プロジェクトに「Welcome#index」という静的ページが作成してあります。また、ユーザー認証構築用にdeviseを導入して、「Admin」というモデルを作成してあります。そして、1個のブラウザが立ち上がって、ログイン状態になっています。
このアプリのセッションidを削除して、ブラウザをログアウト状態にしてください。
模範解答1
ブラウザの設定メニューからクッキーを削除する
ブラウザの設定ページで「_myblog_session」のクッキーを削除する。