允许未经确认的用户访问某些需要身份验证的页面

时间:2018-08-07 10:31:06

标签: ruby-on-rails ruby-on-rails-3 devise warden devise-confirmable

我将Rails Stack与

一起使用
  • 设计
  • 监护人
  • 可确认

现在,我对电子邮件确认和未验证用户的访问权限有一定要求。假设页面分为3类:

  1. case 1-不需要身份验证。
  2. case 2-需要认证,还需要确认用户。
  3. case 3-需要进行身份验证(正确的用户名和密码组合),但无需确认用户即可访问它们。

通过设计和确认,实现case 1case 2轻而易举。用户登录/注册后,我将重定向至“确认您的电子邮件页面”。

我的问题是case 3。假设用户进行了登录/注册。他尚未确认自己的电子邮件地址,但应被允许访问某些case 3路线。当他访问案例3的路线时,我期望:

  • 不重定向
  • 有效会话

具有确认的设计要么允许确认的用户访问所有页面,要么不允许。它不允许访问带有身份验证但未经确认的某些页面。

我尝试通过实现以下逻辑来覆盖设计confirmed?

class ApplicationController < ActionController::Base
   before_filter :verify_user
   def verify_user
       $flag = true if CERTAIN_ROUTES.include?(action_class)
   end
end

class User < ActiveRecord::Base
   def confirmed?
      $flag || !!confirmed_at
   end
end

这几乎不能用于登录,但不能用于注册。同样,这是实现它的极其糟糕的方法。我应该如何解决这个问题?其他功能正常工作。

2 个答案:

答案 0 :(得分:5)

除了覆盖confirmed?之外,您还可以覆盖confirmation_required?模型方法(docs)

# user.rb
class User < ActiveRecord::Base
  protected

  def confirmation_required?
    false
  end
end

此后,您可以自己处理确认逻辑,方法是在控制器需要确认时通过在before_action中重定向所有未确认的用户,也可以将其纳入授权逻辑中(例如,使用专家)。

class ApplicationController < ActionController::Base
   def needs_confirmation
     redirect_to root_path unless current_user.confirmed?
   end
end

class SomeController < ApplicationController
  before_action :needs_confirmation
end

答案 1 :(得分:2)

您应该看一下宝石'pundit'-它与devise配合得很好。

https://github.com/varvet/pundit

您编写的策略将涵盖每个授权要求,而不是编写控制器的before_actions等,然后在控制器内部使用这些策略。

例如,在控制器中:

    SELECT '[' + s.name + '].[' + o.name + '].[' + i.name + ']' AS keyname
    from sys.foreign_keys i
    INNER JOIN sys.objects o ON i.parent_object_id = o.object_id
    INNER JOIN sys.schemas s ON o.schema_id = s.schema_id
    WHERE i.is_not_trusted = 1 AND i.is_not_for_replication = 0;

然后,您的政策将保存在app / policies / example_policy.rb

class ExampleController < ApplicationController
    before_action { authorize :example }

    def case_one
       # action
    end

    def case_two
       # action
    end

    def case_three
       # action
    end
end

它真的很好用,特别是在您要确定针对某种资源的授权的其他情况下。