授权的最佳实践是什么?

时间:2021-12-31 15:41:53

Situation: rails 3.2 app with a demo period, after which users must start paying for the service.

情况:rails 3.2应用程序演示期间,用户必须开始为服务付费。

Question: If a user does not add a payment method, or does not choose a payment plan, what is the recommended way of restricting user access to the 'paid' part of the web app?

问:如果用户不添加支付方式,或者不选择支付计划,那么限制用户访问web应用“付费”部分的推荐方式是什么?

I need something that sorts users as follows:

我需要一些可以对用户进行排序的东西:

if user.admin? || user.in_demo || user.has_all_payment_data
  # carry on
elsif user.should_add_payment_method
  # send them to add payment method page
elsif user.should_choose_plan
  # send them to add plan
else
  # redirect to home page or whatever
end

I've started off with a before_filter on the application controller that checks the payment status of the user on every request and redirects them accordingly (skipping this in places like the homepage/profile editing etc.), but I'm thinking there must be a better way, as it's rapidly getting too complicated and it just feels wrong having all that complexity in the application controller. I've been looking at user roles libraries like cancan but I can't find anything that fits.

我一开始用一个before_filter在应用程序控制器检查用户的付款状态对每个请求并相应地重定向(跳过这个在主页/配置文件编辑等等),但是我想一定有一个更好的方法,因为它是快速变得太复杂,只是感觉不对的所有应用程序复杂性的控制器。我一直在看像cancan这样的用户角色库,但是我找不到适合的。

2 个解决方案

#1


2  

There is a post by Jonas Nicklas (creator of Capybara and CarrierWave) in which he explains in some detail how to take a simpler approach than CanCan's. His approach is based on an additional plain Ruby class for each model you want to create authorization rules for.

在乔纳斯·尼克拉斯(Capybara和CarrierWave的创始人)的一篇文章中,他详细地解释了如何采取比坎坎坎卡更简单的方法。他的方法基于为每个模型创建授权规则的额外纯Ruby类。

Simple authorization in Ruby on Rails apps (Elabs blog)

Ruby on Rails应用程序中的简单授权(Elabs blog)

They have offloaded that solution into a gem named Pundit, but it really seems simple enough to be able to implement from scratch.

他们已经将这个解决方案移植到一个名为Pundit的gem中,但是它看起来真的很简单,能够从头开始实现。

Pundit gem (GitHub)

权威的宝石(GitHub)

#2


1  

I would suggest a before_filter in the application controller, then using skip_filter in individual controllers to bypass it for actions that non-paid users can access, e.g:

我建议在应用程序控制器中使用before_filter,然后在单独的控制器中使用skip_filter,以绕过非付费用户可以访问的操作,例如:

class ApplicationController < ActionController::Base
  before_filter :check_payment
  ...
end

class UserController < ApplicationController
  skip_filter :check_payment, :only => [:login, :logout, ...]
  ...
end

This keeps the access contained to the relevant controllers, rather than needing an increasingly large :except => ... on the filter itself.

这样就可以保持对相关控制器的访问,而不需要越来越大的:except =>…过滤器本身。

#1


2  

There is a post by Jonas Nicklas (creator of Capybara and CarrierWave) in which he explains in some detail how to take a simpler approach than CanCan's. His approach is based on an additional plain Ruby class for each model you want to create authorization rules for.

在乔纳斯·尼克拉斯(Capybara和CarrierWave的创始人)的一篇文章中,他详细地解释了如何采取比坎坎坎卡更简单的方法。他的方法基于为每个模型创建授权规则的额外纯Ruby类。

Simple authorization in Ruby on Rails apps (Elabs blog)

Ruby on Rails应用程序中的简单授权(Elabs blog)

They have offloaded that solution into a gem named Pundit, but it really seems simple enough to be able to implement from scratch.

他们已经将这个解决方案移植到一个名为Pundit的gem中,但是它看起来真的很简单,能够从头开始实现。

Pundit gem (GitHub)

权威的宝石(GitHub)

#2


1  

I would suggest a before_filter in the application controller, then using skip_filter in individual controllers to bypass it for actions that non-paid users can access, e.g:

我建议在应用程序控制器中使用before_filter,然后在单独的控制器中使用skip_filter,以绕过非付费用户可以访问的操作,例如:

class ApplicationController < ActionController::Base
  before_filter :check_payment
  ...
end

class UserController < ApplicationController
  skip_filter :check_payment, :only => [:login, :logout, ...]
  ...
end

This keeps the access contained to the relevant controllers, rather than needing an increasingly large :except => ... on the filter itself.

这样就可以保持对相关控制器的访问,而不需要越来越大的:except =>…过滤器本身。