#はじめに
右も左もわからないプログラミング初心者が書く備忘録です。
膨大な勉強量の中で気になった事をメモしていきます。
今回ポートフォリオの作成ともあり、管理者ページに転移する際にパスワードを求めたくない
(担当の方に余計な一手を打たせたくない)という理由からはじめました
しかし、普通に運用する際もセキュリティの向上が期待できると思いますので
パスワードのみでブロックしている方などは参考にしてみてください♪
#今回の内容
gem 'devise'
gem 'cancancan'
gem 'rails_admin', '~> 2.0'
を使用し、webアプリに管理者ページを作成したいと思います
管理用ページのアクセスに関して
・アクセス可能なのは管理者のみ
・他のユーザーはアクセス不可(トップページへ飛ばす)
・ログインしていない場合、ログインページへ移動させる
を意識していきたいと思います
#開発環境
Rails 6.1.3.2
ruby 2.5.1
Docker version 20.10.6
devise (4.8.0)
cancancan (3.3.0)
rails_admin (2.2.1)
RailsAdmin 2.0.1、2.0.0、および1.4.2までは、XSSの脆弱性があると報告されています。
#事前準備
今回、DeviseによるuserのCRUDは出来ているものとします
まだの方は導入が終わってからお進みください♪
以下記事がSNS認証を含めていますが、とても参考になると思います!
deviseの導入が終わったら、まずは管理者権限を付与するためにUserテーブルにadminを追加します
$ rails g migration AddAdminToUsers
上記コマンドで出来たマイグレーションファイルを編集します
class AddAdminToUsers < ActiveRecord::Migration
def change
add_column :users, :admin, :boolean, default: false
end
end
$ rails db:migrate
これでadminという真偽値を持つカラムができました
これを利用し
true => 管理者権限あり
false => 一般ユーザー
と区分けをする事ができます♪
ユーザーが新規作成された時はfalseが入る(一般ユーザーに該当する)ようになっています
既に権限を付与したいユーザーが存在する場合
以下コマンドで管理者権限を付与してください
$ rails c
$ User.all
ここで権限を付与したいユーザーのIDを確認します
$ user = User.find(権限を付与したいユーザーのID)
userという変数に権限を付与したいユーザーが入ります
$ user.admin = true
ユーザーのadminをtrueにして管理者権限を付与します
$ user.save
設定を保存します
次にGemの追加です
gem 'cancancan'
gem 'rails_admin', '~> 2.0'
$ bundle install
ここからは順を追って説明します
#rails_admin
とてもわかり易いので一読してみてください♪
$ rails g rails_admin:install
Running via Spring preloader in process 23
? Where do you want to mount rails_admin? Press <enter> for [admin] >
route mount RailsAdmin::Engine => '/admin', as: 'rails_admin'
create config/initializers/rails_admin.rb
環境により、名前を付けてくれと言われるかもしれません
# この文章です
? Where do you want to mount rails_admin? Press <enter> for [admin] >
変える必要がなければ、そのままEnterを押してください
これだけで、トップページのURLに /admin をつけてあげれば管理用ページに入れます
とても簡単ですよね♪
まずは簡単な設定を行います(コメントアウトを外すだけ)
## == Devise ==
config.authenticate_with do
warden.authenticate! scope: :user
end
config.current_user_method(&:current_user)
## == CancanCan ==
config.authorize_with :cancancan
###後ほど、重要な設定を行いますので気に留めておいてください
#cancancan
管理者以外をトップページに飛ばすという工程を担当してもらうために導入します
最初はrails_adminのコントローラーの名前空間を利用して
redirectさせれば良いかと思っていたのですが、なかなかに手間なのでcancancanを使用します
使いこなせばとても便利なGemですので調べてみてください♪
こちらもとてもわかり易いので御一読を
$ rails g cancan:ability
Running via Spring preloader in process 21
create app/models/ability.rb
上記コマンドで出来たファイルを修正します
コメントアウトされている箇所は、丁寧に説明してくれている文なので
翻訳して見ておきましょう♪
(確認後、私は削除しました)
class Ability
include CanCan::Ability
def initialize(user)
if user && user.try(:admin?)
can :access, :rails_admin
can :manage, :all
end
end
end
#テストしてみる
1.ログインせずに管理者ページへ
=>deviseの効果でログイン画面へ
2.管理者権限を付与したユーザーで管理ページへ
=>管理ページへ転移
3.権限のないユーザーで管理ページへ
=>エラー!!!
という結果になると思います
#エラー内容
権限を付与していないのであたりまえなのですが、このページにアクセスする権限がありませんとのこと
ですがエラーを出すのではなく、トップページへ転移して欲しい!!!
#修正箇所
今回のキモとなるコードです
###config.parent_controller = 'ApplicationController'
この記載がないと、application_controller.rbにコードを書いても読まれません
config.parent_controller = 'ApplicationController' # これを追加
# 以下はそのまま
### Popular gems integration
## == Devise ==
config.authenticate_with do
warden.authenticate! scope: :user
end
config.current_user_method(&:current_user)
## == CancanCan ==
config.authorize_with :cancancan
rescue_from CanCan::AccessDenied do |exception|
respond_to do |format|
format.json { head :forbidden }
format.html { redirect_to main_app.root_path, alert: "管理者権限がないのでアクセスできません" }
end
end
この記述をしてあげれば、エラーがなくなり
権限を持たないユーザーが管理用ページに入ろうとした時にトップページへ転移させることができます
" alert: "管理者権限がないのでアクセスできません" "
の部分は好きな文言に変えて使用してください
また、viewファイルでは
<% if user_signed_in? && current_user.admin == true %>
<!-- 管理者にのみ表示したい内容例 -->
<%= link_to '/admin' do %>
<button type="button" class="btn btn-outline-danger admin-btn">管理者用ページはこちら!</button>
<% end %>
<% end %>
などで、管理者のみ管理用ページへのリンクを表示させるなどしておきましょう!
rails_adminを日本語化する
現状、管理用ページの一番上に
”日本語になってないよ!”
と記載されていると思います。
実際にページ内は英語で書かれていると思いますが
管理する際、適宜日本語化しておいたほうが気持ちいいので変えていきます
今回はこの方のコードをお借りしました
今回はわかりやすくするため、config/locales配下に専用のファイルを作りました
コピーしたコードを貼り付けてください
モデル名なども日本語化したければ追加で記述してあげれば大丈夫だと思います
そして gem 'rails-i18n' を導入していないならここで入れておきましょう
gem 'rails-i18n'
$ bundle install
config/apprication.rbに以下を記述
module App
class Application < Rails::Application
・
省略
・
config.i18n.default_locale = :ja
・
省略
・
end
end
以上で管理用ページが実装出来たと思います
今回はあまり時間がなく、ぱぱっと書いてしまいましたので
間違いなど御座いましたらコメントして頂けると幸いです!
#最後に
勉強を始めたばかりで知識もなく、拙い文章ですがアウトプットすることで頭の中を整理しつつ、どなたかのお役に立てれば良いなと思い投稿させて頂きました。
最後まで見て頂きありがとうございました!