Pundit的Rails授权

by Joseph Gefroh

由Joseph Gefroh

Pundit的Rails授权 (Rails Authorization with Pundit)

Pundit is a Ruby gem that handles authorization via a very simple API.

Pundit是一个Ruby gem,它通过非常简单的API处理授权。

Remember that authorization is different from authentication — authentication is verifying that you are who you say you are, and authorization is verifying that you have permission to perform an action.

请记住,授权与身份验证不同–身份验证是在验证您的身份,身份验证是在授权您执行操作。

Pundit is squarely within the authorization camp — use another authentication system like Devise to handle authentication.

Pundit正好位于授权阵营内–使用另一个验证系统(例如Devise)来处理验证。

您如何与Pundit合作 (How you work with Pundit)

Step 1: You create a Policy class that deals with authorizing access to a specific type of record — whether it be a Blog or Potato or User.

步骤1:您创建一个Policy类,该类处理授权对特定记录类型的访问-无论是BlogPotato还是User

Step 2: You call the built-in authorize function, passing in what you’re trying to authorize access to.

步骤2:您调用内置的authorize函数,传递您要授权访问的内容。

Step 3: Pundit will find the appropriate Policy class and call the Policy method that matches the name of the method you are authorizing. If it returns true, you have permission to perform the action. If not, it’ll throw an exception.

步骤3: Pundit将找到适当的Policy类,并调用与您授权的方法名称匹配的Policy方法。 如果返回true,则您有权执行该操作。 如果没有,它将引发异常。

It’s pretty straightforward. Logic for specific models is encapsulated into its own policy class, which is great for keeping things tidy. Competing authorization library cancancan had issues with complicated permissions getting out of hand.

这很简单。 特定模型的逻辑封装在其自己的策略类中,这对于保持事物整洁很有用。 竞争授权库可能会遇到复杂权限无法控制的问题。

需进行细微调整 (Minor tweaks required)

Pundit’s simple conventions sometimes need to be tweaked to support more complex authorization use cases.

有时需要调整Pundit的简单约定,以支持更复杂的授权用例。

从策略中访问更多信息 (Access more information from within a Policy)

By default, Pundit provides two objects to your authorization context: the User and the Record being authorized. This is sufficient if you have system-wide roles in your system like Admin or Moderator, but isn’t enough when you need authorize to a more specific context.

默认情况下,Pundit为您的授权上下文提供两个对象: User和被授权的Record 。 如果您在系统中具有系统范围的角色(例如AdminModerator ,这就足够了,但是当您需要授权到更特定的上下文时,这还不够。

Let’s say you had a system that supported the concept of an Organization, and you had to support different roles within those organizations. System-wide authorization won’t cut it — you don’t want an admin of Organization Potato to be able to do things to Organization Orange unless they are an admin of both organizations. When authorizing this case, you would need access to 3 items: the User, the Record, and the user’s role information in the Organization. The ideal case would be to have access to the organization the record belongs to, but let’s make it harder and say we don’t have access to that via the record or the user.

假设您有一个支持Organization概念的系统,并且必须支持这些组织内的不同角色。 系统范围内的授权不会减少麻烦–您不希望Organisation Potato的管理员能够对Organization Orange进行操作,除非他们是两个组织的管理员。 当授权这种情况下,你将需要访问3个项目:该UserRecord ,并在用户的角色信息Organization 。 理想的情况是可以访问记录所属的组织,但是让我们变得更加困难,说我们无法通过记录或用户访问记录。

Pundit provides an opportunity to provide additional context. By defining a function called pundit_user, this allows you to change what is considered a user. If you return a object with the authorization context from that function, that context will be available to your policies.

Pundit提供了提供其他上下文的机会。 通过定义一个名为pundit_user的函数,您可以更改被认为是user 。 如果从该函数返回具有授权上下文的对象,则该上下文将可用于您的策略。

application_controller.rb

application_controller.rb

class ApplicationController < ActionController::Base  include Pundit
def pundit_user    AuthorizationContext.new(current_user, current_organization)  endend

authorization_context.rb

authorization_context.rb

class AuthorizationContext  attr_reader :user, :organization
def initialize(user, organization)    @user = user    @organization = organization  endend

application_policy.rb

application_policy.rb

class ApplicationPolicy  attr_reader :request_organization, :user, :record
def initialize(authorization_context, record)    @user = authorization_context.user    @organization = authorization_context.organization    @record = record  end
def index?    # Your policy has access to @user, @organization, and @record.    endend

Your policies would now have access to all three kinds of information — you should be able to see how you would access more information if you needed it.

现在,您的策略将可以访问所有三种信息-您应该能够看到在需要时如何访问更多信息。

覆盖约定并指定要使用的策略 (Override convention and specify which Policy to use)

Pundit uses naming conventions to match up what you’re trying to authorize with the right policy. Most of the time this works well, but in certain cases you may need to override this convention, such as when you want to authorize a general dashboard action that doesn’t have an associated model. You can pass in symbols to specify which action or policy to use for authorization:

Pundit使用命名约定来匹配您要使用正确的策略授权的内容。 在大多数情况下,此方法运行良好,但在某些情况下,您可能需要覆盖此约定,例如,当您要授权没有关联模型的常规仪表板操作时。 您可以传入符号以指定用于授权的操作或策略:

#Below will call DashboardPolicy#bake_potato?authorize(:dashboard, :bake_potato?)

If you have a model that is named differently, you can also override the policy_class function within the model itself:

如果您有一个名称不同的模型,则还可以在模型本身内覆盖policy_class函数:

class DashboardForAdmins  def self.policy_class   DashboardPolicy     # This forces Pundit to use Dashboard Policy instead of looking    # for DashboardForAdminsPolicy  endend

测试中 (Testing)

Authorization is one of those things I strong recommend having an automated test suite around. Setting them up incorrectly can be catastrophic, and it’s in my opinion one of the most tedious things to test manually. Being able to run a single command and knowing that you haven’t inadvertently changed any authorization business rules is a great feeling.

授权是我强烈建议使用的自动化测试套件之一。 错误地设置它们可能会造成灾难性的后果,在我看来,手动测试是最繁琐的事情之一。 能够运行单个命令并知道您没有无意中更改了任何授权业务规则,这是一种很棒的感觉。

Pundit makes testing authorization very simple.

Pundit使测试授权非常简单。

def test_user_cant_destroy?  assert_raises Pundit::NotAuthorizedError do    authorize @record, :destroy?  endend
def test_user_can_show?  authorize @record, :show?end

Overall I like Pundit. I’ve only been using it for a short while, but I already prefer it over cancancan — it just feels more maintainable and testable.

总的来说,我喜欢Pundit。 我仅使用了短时间,但我已经喜欢它而不是cancancan -它感觉更易于维护和测试。

Did you find this story helpful? Please Clap to show your support!If you didn’t find it helpful, please let me know why with a Comment!

您觉得这个故事对您有帮助吗? 请鼓掌表示支持!如果您没有找到帮助,请在评论中告诉我原因!

翻译自: https://www.freecodecamp.org/news/rails-authorization-with-pundit-a3d1afcb8fd2/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值