日本語版
最新ニュース
科学&テクノロジー

Rails 7 での認証と認可

承認とは、現在のユーザーに一部の URL (より一般的には、あらゆる種類のリソース) へのアクセスを許可または拒否することを意味します。これは認証と密接に関係していますが、異なります。気候変動に関する国際会議について考えてみましょう。認証は入場券であり、チケットがなければカンファレンスに入場することはできません。承認とは、アクセスのチケット レベルを確認することです。ゲート A またはスナック B へのアクセスを許可しますか?Rails 7 での認証Rails は認証用のジェネレーターを推奨しているようです (Rails 8 ではそうなるでしょう) ので、(現時点では) 最も近い可能性である auth-zero ジェネレーターを使用してみましょう。前提条件このチュートリアルで使用するツール1 2 3 4 5 ruby -v # 3.3.0 rails -v # 7.1.3 bundle -v # 2.4.10 node -v #…

Rails 7 での認証と認可

1707736774
2024-02-12 09:37:46

承認とは、現在のユーザーに一部の URL (より一般的には、あらゆる種類のリソース) へのアクセスを許可または拒否することを意味します。

これは認証と密接に関係していますが、異なります。

気候変動に関する国際会議について考えてみましょう。

認証は入場券であり、チケットがなければカンファレンスに入場することはできません。

承認とは、アクセスのチケット レベルを確認することです。ゲート A またはスナック B へのアクセスを許可しますか?

Rails 7 での認証

Rails は認証用のジェネレーターを推奨しているようです (Rails 8 ではそうなるでしょう) ので、(現時点では) 最も近い可能性である auth-zero ジェネレーターを使用してみましょう。

前提条件

このチュートリアルで使用するツール

1
2
3
4
5
ruby -v # 3.3.0
rails -v # 7.1.3
bundle -v # 2.4.10
node -v # 20.9.0
git --version # 2.34.1

認可・認証前

Rails は認証用のジェネレーターを推奨しているようです (Rails 8 ではそうなるでしょう) ので、(現時点では) 最も近い可能性である auth-zero ジェネレーターを使用してみましょう。

それでは、認証システム (CSS なし) を構築することから始めましょう

1
2
3
4
5
rails new myapp
cd myapp 
bundle add authentication-zero
bin/rails generate authentication

素晴らしい! これで、認証機能が強化されたデフォルトの Rails アプリが完成しました。

データベースをシードして作成する

db/seeds.rb 内

1
User.create(email: "[email protected]", password_digest: BCrypt::Password.create("Secret1*3*5*"), verified: true)

次にデータベースを作成します

1
2
3
4
5
6
 
 # Create database and schema.rb
 bin/rails db:create
 bin/rails db:migrate
 bin/rails db:seed

そしてサーバーを起動します:

1
2
 # Launch the local web server
 bin/rails server

良い! 次に、localhost:3000 を開き、seed.rb 内にあるユーザーで認証を試みます。

ここでログアウトし、ローカル Web サーバーを停止します。

3 つの異なるページを作成する

次に、ホームページ、プロフィール ページ、管理者ページの 3 つの異なるページを作成しましょう。

このようなようこそページ:

1
2
3
4
5
 echo "class WelcomeController < ApplicationController" > app/controllers/welcome_controller.rb
 echo "end" >> app/controllers/welcome_controller.rb
 mkdir app/views/welcome
 echo '

welcome page

'
> app/views/welcome/index.html.erb

このようなプロフィールページ:

1
2
3
4
5
 echo "class ProfileController < ApplicationController" > app/controllers/profile_controller.rb
 echo "end" >> app/controllers/profile_controller.rb
 mkdir app/views/profile
 echo '

Profile page

'
> app/views/profile/index.html.erb

そして、次のような管理ページ:

1
2
3
4
5
 echo "class AdminController < ApplicationController" > app/controllers/admin_controller.rb
 echo "end" >> app/controllers/admin_controller.rb
 mkdir app/views/admin
 echo '

Admin only area!

'
> app/views/admin/index.html.erb

次に、これらの新しいページにルートを適用します。

1
2
3
4
5
6
7
8
9
10
11
12
 # inside config/routes.rb
 Rails.application.routes.draw do

  # add these 3 lines
  get "welcome", to: "welcome#index"
  get "profile", to: "profile#index"
  get "admin", to: "admin#index"

  # all other routes remain unchanged
  # ...

 end

ローカル Web サーバーを再起動し、次の URL にアクセスしてみます。

  • 「http://locahost:3000/welcome」、ウェルカムページ
  • 「http://locahost:3000/profile」、プロフィールページ
  • 「http://locahost:3000/admin」、管理者専用エリア 😉

うわぁ! ログイン画面を通過しない限り、いずれも使用できません。

多くの Rails プロジェクトで見られる良い実践は、すべてのルートをデフォルトで「認証」することです。つまり、すでに認証されていない限り、ルートにアクセスすることはできません。

ページを一般公開する

HomeController を次のように変更します。

1
2
3
4
5
6
# Inside app/controllers/welcome_controller.rb
class WelcomeController < ApplicationController

 skip_before_action :authenticate # add this

end

なるほど、公平ですね。 認証が必要なウェルカム ページはほとんど表示されません。

そこで、もう一度ようこそページ (http://locahost:3000/welcome) を開くと、認証を必要とせずにアクセスできるようになります。

役割列を追加

承認は認証にリンクされていますが、まったく同じものではないことに注意してください。

  • 単純な訪問者はホームページを表示できますが、ユーザー プロフィール ページにはアクセスできません。
  • ユーザーはホームページとプロフィール ページにアクセスできますが、管理ダッシュボードにはアクセスできません
  • 管理者はアプリケーションのあらゆる部分にアクセスできます

したがって、それを知るためには「役割」列が必要です。 誰が にアクセスできます

ローカル Web サーバーを停止します

ターミナルに戻り、次のように入力します。

1
 bin/rails generate migration add_role_to_users role:string

移行ファイルを次のように変更します。

1
2
3
4
5
6
class AddRoleToUsers < ActiveRecord::Migration
 def change
   # modify as follow
   add_column :users, :role, :string, :default => "customer"
 end
end

そして走ります

user.rb 内

1
2
3
4
5
6
7
8
class User < ApplicationRecord
 has_secure_password

 # add this line
 enum role: {customer: "customer", admin: "admin"}

 # ...rest of code
end

データベースにさまざまなプロファイルをシードする

db/seeds.rb 内

1
2
3
User.create(email: "[email protected]", role: 'customer', password_digest: BCrypt::Password.create("Secret1*3*5*"), verified: true)
User.create(email: "[email protected]", role: 'customer', password_digest: BCrypt::Password.create("Secret1*3*5*"), verified: true)
User.create(email: "[email protected]", role: 'admin', password_digest: BCrypt::Password.create("Secret1*3*5*"), verified: true)

データベースを再作成します (実稼働データベースを作成したら、通常はこれを行いませんが、小規模なチュートリアルの場合は問題ありません)。

1
 bin/rails db:drop db:create db:migrate db:seed

次のコマンドでローカル Web サーバーを再起動します。

そして、[email protected] として接続し、localhost:3000/admin にアクセスしてみます。

うわぁ! 顧客として接続した場合でも、管理エリアにアクセスできます。 認証エラーが発生するはずなので、今度は Pundit で認証を行います。

Pundit による Rails 7 の認可 (ついに!)

Pundit を追加して、権限のないユーザーが派手な Web アプリ内のあらゆる場所にアクセスすることを明確に防止します。

追加 gem 'pundit' Gemfile へ:

そして走ります

アプリケーション コントローラーに Pundit を含めます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class ApplicationController < ActionController::Base
  include Pundit::Authorization # add this line

 # was here before, left as-is
 before_action :set_current_request_details
 before_action :authenticate

 # add this method, required by Pundit
 def current_user 
  Current.user # this belongs to the authentication mechanism, so not Pundit
 end

 # rest of code ...

end

また、ジェネレーターを実行して、いくつかの便利なデフォルトを使用してアプリケーション ポリシーをセットアップすることもできます。

1
bin/rails g pundit:install

その後、Rails サーバーを再起動する必要があります。 Rails は新しいクラスのあらゆるクラスを選択できるようになりました。 app/policies/ ディレクトリ。

ポリシーの追加

1
2
touch app/policies/admin_policy.rb

私たちの admin_policy.rb 管理者のみが管理ダッシュボードにアクセスできるようにします。

1
2
3
4
5
6
7
class AdminPolicy < ApplicationPolicy
 attr_reader :user

 def index?
  return user.admin?
 end
end

Pundit ポリシーをコントローラーに挿入する

それでは、ポリシーをコントローラーに注入しましょう。

1
2
3
4
5
6
7
class AdminController < ApplicationController

 def index
  authorize Current.user, policy_class: AdminPolicy
 end 

end

わーい! ここでは Rails の魔法はあまり必要ありません。 現在のユーザーに特定のポリシーを明示的に許可します。

次に、Web サーバーを再起動し、顧客として管理エリアに接続してみます。 エラーが発生するはずです。

管理者として管理領域に接続してみます。 正しく動作するはずです:)

それはどのくらい良いですか?

まとめ

Web アプリの 2 つの主要な概念をゼロから説明しました。

  • ジェネレーターを使用した認証: Rails 8 は次のように動作するため、これを実現するために同様の gem に依存しました。
  • どのユーザーがどのリソースにアクセスできるかを知るための、よく知られた gem を使用した承認。

それでは良い一日をお過ごしください:)

デビッド

#Rails #での認証と認可

執筆者について: nipponese

Nipponese News編集部は、国内外のニュースを日本語で分かりやすくお届けします。