Ruby on Rails の User 認証ライブラリである Devise を使ってみる
初めに¶
以下操作は WSL で実施しています。 Rails の操作ばかりなのでOSには依存しないと思いますが。 Ruby / Rails の環境は以下です。
$ ruby -v
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-linux]
$ rails -v
Rails 6.0.0
Getting Started をなぞる¶
インストール¶
Deviseをテストするために新規プロジェクト作成。 既にプロジェクトがあってそこでテストできるならここは別にやらなくてもよいです。
rails new devise_test -d postgresql
# プロジェクトの作成が完了したら移動
cd devise_test
devise を入れるために Gemfile に以下の記述を追加する。
gem 'devise'
Gemfile の内容を更新したので Bundle を利用してインストール。 bundle コマンド単体で bundle install の効果があります。
bundle
rails generate により、 devise の最低限必要な設定ファイルを生成する。
rails generate devise:install
この時に以下のファイルが生成されているはず。
create config/initializers/devise.rb
create config/locales/devise.en.yml
本家サイトの Getting Started によると、 これらの設定ファイルを絶対読め、と書いてあるので読みましょう。 といっても Devise の設定ファイルとLocalizationファイルなので片方は読むというほどでもない気がしますが。 まぁ何となく雰囲気だけ察する感じで。
そして、さっきのコマンドで以下のようなガイドが表示されるので対応していく。
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. 環境設定ファイルにデフォルトURLオプションを設定したか確かめてください。
例えばDevelopment環境だと以下の値を config/environments/development.rb に入れると良いでしょう。
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
Production環境では適切な設定に替えてください。
2. config/routes.rb で root URL をちゃんと設定しているか確かめてください。例えば以下のように。
root to: "home#index"
3. app/views/layouts/application.html.erb で flash しているか確かめてください。例えば以下のように。
<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>
4. DeviseのViewを以下コマンドでコピーできるので、カスタマイズしてみてください。
rails g devise:views
ということで、各インストラクションに従ってみる。
1.にある通り上記の値を指定されたファイルの active_mailer に関する設定がされているあたりに追記。
2.の通りRoot URLを記述。
3.の通りメッセージをFlashするように修正。
4.はまぁいいか。ということでひとまず置いておきます。
モデルの作成¶
さて、ここで認証に使うモデルを作成しましょう。 基本的には User という名前になると思うので、ここでは User ですがどんな名前を使っても構いません。 因みに作成済みのモデルであっても特に問題はないそうです。
rails generate devise User
これにより migration ファイルが作成されるので、内容を確かめましょう。 Devise が必要に応じて機能を追加できるように migration ファイルを作成してくれているので便利ですね。
例えば User のアクティビティを追跡したいのであれば Trackable とコメントのあるあたりのプロパティのコメントを外していきます。同じく、登録時の確認などを実施するのであればConfirmable のセクションを全部コメント外しが必要になります。 これらの変更を加える際には、ファイルの下部に存在する add_index の対応する行もコメント外しするのをお忘れなく。
ここまで来たら migration しましょう。 まだ DB を作ってなかったので db:create も一緒に。
rails db:create
rails db:migrate
これにより何が作成されたかを routes コマンドで確認してみます。
$ rails routes
Prefix Verb URI Pattern Controller#Action
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
user_password PATCH /users/password(.:format) devise/passwords#update
PUT /users/password(.:format) devise/passwords#update
POST /users/password(.:format) devise/passwords#create
cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
new_user_registration GET /users/sign_up(.:format) devise/registrations#new
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
user_registration PATCH /users(.:format) devise/registrations#update
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
POST /users(.:format) devise/registrations#create
root GET / home#index
なんだか色々ありますが、よくよくURLを見ればログインしたりパスワード変更したりと 必要そうなものがそろっていることが分かります。
また、 Devise が最低限のレベルの View も作ってくれているのでこの段階でSignUp/SignOut可能です。 /users/sign_up にアクセスすると、登録画面が出るはずです。
適当に自分のメアドと変なパスワードで登録してみます。 メールは実際には送られません。
登録すると、セッションが作成され自動的にログインするのですが Root URL である Home を特に何も作成していないためエラー画面に遷移させられてしまいますが、 /users/edit にアクセスし直してみると、確かに自分が作成した User でログインできていることが確認できます。
ログイン状態に基づくアクセス制限¶
Getting Startedではこの後アクセス制限の話が出てきます。 アクセス制限をするにも今のままではアクセスするページがないのでそれを作成します。 既にページがある場合は飛ばしてください。
rails g controller home index
これで index 用の Viewを作成しました。 前述の通り Root URL に設定していたのでこれでトップページが home#index になります。
ただこれだけだとテストができないので、アクセス制限テスト用のページを作成し、 home#index からアクセスできるようにします。
中身は適当ですが、 app/views/home/index.html.erb を以下のようにしました。
<h1>Top Page</h1>
<div>
<%= link_to('Test Page', home_test_path) %>
</div>
<div>
<%= link_to('Login', new_user_session_path) %>
</div>
<div>
<%= link_to('Logout', destroy_user_session_path, method: :delete) %>
</div>
これでトップページからログイン、ログアウト、テストページへのアクセスができるようになります。
つづいて、テストページを適当に作ります。 上記の例だと home_test_path とあるように、
- HomeController に test という関数を追加
- app/views/home/test.html.erb というファイルを適当な内容で作成
しています。
さて、ここで home#test にアクセス制限をかけましょう。 簡単にアクセス制限をかけるには before_action :authenticate_user を利用します。 ただし、 HomeController にそのままこの before_action を付けてしまうと全部の関数に制限がかかってしまうので only: により関数を制限します。 具体的には以下のようになりました。
class HomeController < ApplicationController
before_action :authenticate_user!, only: :test
def index
end
def test
end
end
これで rails s によりサーバを起動しアクセスし、 home#test にアクセスするとアクセス制限がかかっていることが分かります。 次にログインしてから同ページにアクセスするときちんと内容が見えます。
コメント
コメントを投稿