Rails5にてユーザー認証を導入する。
ログイン、新規登録など出来るようになる。
※一番最後まで実装すると、最終的に Rails_admin+cancancanで管理画面まで実装してユーザーや投稿の管理一式も実装できる。
deviseを導入する
GemFileを編集
GemFile に
gem 'devise'
これを記述して
$ bundle install
インストールする。
deviseをインストール
$ rails g devise:install
これで、必要なDeviseがインストールされる。
ファイルの編集
config/environments/development.rb に
Don't care if the mailer can't send. の下に
# Don't care if the mailer can't send.
config.action_mailer.default_url_option = {host: 'localhost', port: 3000 }
これを記述する
Userモデルを作成
$ rails g devise User
$ rails db:migrate
rails g devise +モデル名(例えば、User,Adminなど)
1回サーバーをCtrl+Cで止めてから再起動させる
そうしないと、エラーが出るので焦る。
テストユーザーを一括登録
db/seeds.rb に記述する
User.create(email: 'admin@test.com', password: 'password')
User.create(email: 'satou@test.com', password: 'password')
User.create(email: 'suzuki@test.com', password: 'password')
User.create(email: 'tanaka@test.com', password: 'password')
User.create(email: 'test@test.com', password: 'password')
$ rails db:seed
このコマンドで上記の5名のユーザーが登録される。
URL+/users/sign-in でログイン画面が表示される
メモ(後で使う)
制御:全部できない
controllerに
before_action :authenticate_user!
これを追加するとログインしていないときは、ログインページに自動で飛ばす。使い方のイメージとして、ログインしている人以外に見せたくないページとかを作成できる。
例えば、controllers/post_controller.rb に記述すれば、投稿ページを非ログイン(非会員)ユーザーには見せなく出来る。
後で使うと思うので、覚えておく。
Admin管理者の場合は、
before_action :authenticate_admin! にする。
rails g devise Admin(ここの名前)と同じにする様に。
制御:編集削除できない
ログインしていなくても見れるが、ログインしてないと
編集できない、削除できない様にする為には
before_action :authenticate_user!, only: [:edit, :update, :destroy]
これを記述する
制御:閲覧だけできる
before_action :authenticate_user!, only: [:edit, :update, :destroy, :new, :create]
これでログインしなくても閲覧だけ出来る状態になる。
よくある制御でたくさん使うと思うので覚えておく。
ついでに
名前のカラムを追加する
$ rails g migration AddNameToUser name:string
$ rails db:migrate
これで Userに名前のカラムを追加できた。
Email+Password+名前の登録が出来るはず。
$ rails c
> User.all
> exit
データベースをコンソールで確認するには rails c で
確認できる。
ユーザー名を保存する
controllers/application_controller.rb に追加する
before_action :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: [:name])
devise_parameter_sanitizer.permit(:account_update, keys: [:name])
end
これで、名前が保存できる様になる。
この後 Veiwsも変更する。
deviseの Viewsを変更できる様にする
$ rails g devise:views User
このコマンドで、ログイン周りのViewsを作成できる。
これやらなと、Veiwsに無い。
さらにこれだけだと、いくらViewsを修正しても動かない。
なので下記のコメントを修正すること。
config.scoped_views = true
上記のコメントアウトを外してtrueに変更する。
これでViewsを変更できる様になる。
変更するViews
views/users/registrations/edit.html.erb
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
</div>
views/users/registrations/new.html.erb
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
</div>
deviseを日本語化する
gem 'devise'
gem 'devise-i18n'
gem 'devise-i18n-views' #いるかわからないけど入れました。
コマンド実行一覧(手順)★
忙しい時は一気にここから見直せばOKです。
$ bundle
$ rails g devise:install
# 既に上の説明までで作ってあればコマンドの必要は無い。
$ rails g devise user
# 既に上の説明までで作ってあればコマンドの必要は無い。
$ rails g devise admin
# adminのモデルを作成する。(NEW)
$ rails g devise:i18n:views user
# user のViewsを作成(NEW)
# rails g devise:i18n:views で作るとViewsフォルダがdevise フォルダ名として作成されてしまうので
# はじめから user を入れておくとフォルダ名がusersで作成してくれる。
$ rails g devise:i18n:views admin
# admin のViewsを作成(NEW)
# rails g devise:i18n:views で作るとViewsフォルダがdevise フォルダ名として作成されてしまうので
# はじめから admin を入れておくとフォルダ名がadminsで作成してくれる。
# 管理者とユーザーを分けるならはじめからこうした方が都合がいい。
$ rails g devise:controllers users
# usersのコントローラーを作成
# 既に上の説明までで作ってあればコマンドの必要は無い。
$ rails g devise:controllers admins
# adminsのコントローラーを作成
# 既に上の説明までで作ってあればコマンドの必要は無い。
$ rails g migration AddNameToUser name:string
# 新規登録時にuser の名前を登録できる様にしておく為、追加
# 既に上の説明までで作ってあればコマンドの必要は無い。
$ rails g migration AddNameToAdmin name:string
# 新規登録時にadmin の名前を登録できる様にしておく為、追加
# 既に上の説明までで作ってあればコマンドの必要は無い。
$ rails db:migrate
UserとAdminを分けたので、routes.rb も変更する。
userとadminを分けたらRoutes設定
Rails.application.routes.draw do
# devise_for :admins
# devise_for :users
devise_for :admins, controllers: {
sessions: 'admins/sessions',
passwords: 'admins/passwords',
registrations: 'admins/registrations'
}
devise_for :users, controllers: {
sessions: 'users/sessions',
passwords: 'users/passwords',
registrations: 'users/registrations'
}
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
これだけだとまだ日本語にならない。
Localeを指定する
locale の指定を追加する。
module testname
class Application < Rails::Application
config.load_defaults 5.2
# これの1行を追加する
config.i18n.default_locale = :ja
end
end
日本語ファイルと英語ファイルを作成
$ rails g devise:i18n:locale ja
$ rails g devise:i18n:locale en
$ rm config/locales/devise.en.yml
devise.en.yml は削除する。
/config/locales/devise.views.en.yml
/config/locales/devise.views.ja.yml
に devise: と書かてれいるそれぞれ1ヵ所づつあるので
users: に修正する。
# devise:
users:
# devise:
users:
これで日本語と英語の言語対応ができた。
ユーザー部分だけ日本語化している状態
/config/locales/devise.views.en.yml
/config/locales/devise.views.ja.yml
上記の2点を変更するとユーザーログインまわり部分は日本語化されているが
Admin部分は日本語化されてない。
その為、devise.views.ja.yml、devise.views.en.ymlに
users:とuser: と書かれている部分を丸ごとそれぞれ複製する。
複製したら複製したusers:→admins: と複製したuser:→admin:へ書き換えれば、アドミン上でも日本語化される。
devise.views.en.yml、devise.views.ja.yml共に行うこと。
日本語化で参考にしたサイト
deviseで大ハマり
Herokuで何度もリジェトされて大ハマりした話。
devise 使うときシークレットキーが必要な様だ。
※このことを知らずに、Gitを疑い、消しては上げ、消してはあげを繰り返しました。
シークレットキー必要なんて書きましたが、すでに記載されているので、コメントを外せばOKです。
エラーログにこんな感じでエラーが出ます。
Devise.secret_key was not set. Please add the following to your Devise initializer:
config.secret_key = '****'
Please ensure you restarted your application after installing Devise or setting the key.
これで解決
config/initializers/devise.rb
config.secret_key = ''
シークレットキーの部分をコメント解除すればOKです。
またはキーをいれて再度 git push heroku master すればOK
ユーザー管理も一緒に入れる
Gemfile追加
gem 'cancancan'
gem 'rails_admin'
Gemファイルに2つを追加します。
コマンド流れ一覧
$ bundle
$ rails g cancan:ability
$ rails g rails_admin:install
# このときパスワードを聞かれますが、そのままenterキーでOKです。
# https:~/admin でログインできます。
$ rails g migration AddAdminFlgToUser admin_flg:boolean
# userテーブルにフラグを追加。trueのユーザーのみ管理者として扱います。
# これを入れることで、管理者に指定されていないユーザーは入れません。
$ rails db:migrate
管理者ユーザーを選択
$ rails c
> user = User.find(1)
> user.update_attribute(:admin_flg, true)
1番目のユーザーを管理者にしました。
追加した場合はUser.find(1)の数字を変えます。
# == Devise ==
config.authenticate_with do
warden.authenticate! scope: :user
end
config.current_user_method(&:current_user)
# == Cancan ==
config.authorize_with :cancan
コメントアウトを外します。
管理画面権限処理
class Ability
include CanCan::Ability
def initialize(user)
if user && user.admin_flg?
can :access, :rails_admin
can :manage, :all
end
end
end
admin_flgによってアクセス権があるかどうかを判定する処理を追加します。
Herokuへデプロイ後
$ heroku run --app testappname rails db:migrate
$ heroku run --app testappname rails c
> user = User.find(1)
> user.update_attribute(:admin_flg, true)
◆
これで、ユーザー登録からユーザー管理、投稿内容管理、日本語変換まで一式実装できるようになったと思います。
あとはこれに
- User Showを追加してプロフィールの様なものを追加
- ユーザーEdit更新時にパスワード要求不要に
- carrierwave+mini_magick+fog-awsでユーザーにアバターを追加してAWSのS3に保存
- 常時SSL化
この辺いれれば一通り。
◆
1年前にメモ用に書いた内容も追記していったらちょうど1年たってました。
1年もたつとやれること増えるんだなと。