【问题标题】:authenticated and unauthenticated routes in rails 5rails 5中经过身份验证和未经身份验证的路线
【发布时间】:2018-02-20 03:58:37
【问题描述】:

我已将我的 rails 4 应用程序更新为 Rails 5,但我无法在 rails 5 上设置经过身份验证和未经身份验证的路由。

在轨道 4 中:

unauthenticated do
   root to: "home#index", as: :unauthenticated_root
end

authenticated :user do
  root :to => "home#dashboard"
end

但是如何为 rails 5 应用程序设置

【问题讨论】:

    标签: ruby-on-rails devise


    【解决方案1】:

    这是一个很好的使用路由约束的应用程序。考虑以下几点:

      # routes.rb
    
      scope module: 'authenticated', constraints: AuthConstraint.new { |user| user.present? } do
        # Management dashboard
        root 'dashboards#index'
      end
    
      root 'home#index'
    

    约束在app/constraints/auth_constraint.rb 文件中定义,可以根据需要进行配置。例如。

    # app/constraints/auth_constraint.rb
    
    class AuthConstraint
      def initialize(&block)
        @block = block || ->(_) { true }
      end
    
      def matches?(req)
        user = current_user(req)
        user.present? && @block.call(user)
      end
    
      def current_user(req)
        User.find_by_id(session[:user_id])
      end
    end
    

    这是一种基于任何所需变量(角色、身份验证等)定义路由访问的灵活方法

    这是 Rails 文档中约束的链接:https://guides.rubyonrails.org/routing.html#specifying-constraints

    【讨论】:

      【解决方案2】:

      我认为您找到了解决方案,如果 user_signed_in 然后重定向到 home#dashboard 否则 "home#index",对吗?那么

      首先,请参阅此解决方案,该解决方案说 How To: Define a different root route for logged in out users 如果它不起作用,请转到下面。


      routes.rb

      root to: "home#index", as: :unauthenticated_root
      get 'dashboard', to: "home#dashboard" #=> dashboard_path
      

      在您的索引操作上使用如下

      def index
          redirect_to dashboard_path if user_signed_in?
      end
      

      使用这个顶部的控制器

      before_action :authenticate_user!, except: [:index]
      

      将设置dashboard和除index以外的其他动作需要认证,你也可以这样使用

      before_action :authenticate_user!, only: [:dashboard]
      

      它将被设置为只需要对dashboard 操作进行身份验证。

      user_signed_in?authenticate_user! 是回调方法,如果你使用 devise 则默认存在,如果你不使用 devise,我相信你有自己的回调方法,只需替换它。

      评论后完全格式化

      class HomeController < ApplicationController
          before_action :authenticate_user!, except: [:index]
      
          def index 
              redirect_to dashboard_path if user_signed_in?
          end
      
          def dashboard 
          end
      
          def other_action 
          end
      
          .....
      end
      

      后耙路线

      unauthenticated_root GET    /                       home#index
      dashboard GET               /dashboard(.:format)    home#dashboard
      

      Update after comment

      如果您有 ajax 登录,请关注此SO question

      您应该覆盖设计创建方法并通过正确呈现视图来管理那里的情况,否则,正如您在设计的默认创建方法中看到的那样,如果未执行会话创建,它只会重定向您而无需渲染create.js

      您可以覆盖控制器文件夹中的设计控制器并命名为registrations_controller.rb,如下所示

      class RegistrationsController < Devise::RegistrationsController
          # POST /resource
          def create
              super
          end
      end
      

      路线看起来像

      devise_for :users, :controllers => {:registrations => 'registrations'}
      

      希望对你有帮助

      【讨论】:

      • 但是当登录到仪表板后,会话会被自动销毁。
      • 及其显示消息“您需要先登录或注册才能继续。”请帮助如何解决此问题。
      • @vishalyadav 我不知道发生了什么,请参阅我的答案下方的编辑部分评论后完全格式化,我已经编写了完全格式化的代码,它实际测试并运行了我的现场项目,我相信这段代码没有问题,如果你手头没有工作,那么需要在真正重要的地方重构整个项目。
      • 谢谢,是的,您的代码正在运行。但是当登录后转到仪表板然后会话被破坏。在控制台中显示渲染的 devise/sessions/create.js.erb (11674.3ms) 在 15435ms 内完成 200 OK (查看次数:11776.6ms | ActiveRecord: 72.2ms) 于 2018-02-27 08 开始为 ::1 获取“/dashboard” :54:38 +0530 HomeController#dashboard 处理为 HTML 完成 401 Unauthorized in 1ms (ActiveRecord: 0.0ms) 请给我任何正确的建议来解决这个问题。谢谢
      • 您应该覆盖设计创建方法并通过正确呈现视图来管理那里的情况,否则,正如您在设计的默认创建方法中看到的那样,如果未执行会话创建,它只会重定向你而不渲染 create.js。请参阅下面 Below Section @vishalyadav 中的答案
      【解决方案3】:

      保护拆分仪表板的示例(用于 A/B 测试的 gem):

      # config/routes.rb
      require "split/dashboard"
      
      class AuthConstraint
        def initialize(&block)
          @block = block
        end
      
        def matches?(request)
          @block.call(current_user(request))
        end
      
        def current_user(request)
          return if request.session[:user_id].blank?
          User.find_by(id: request.session[:user_id])
        end
      end
      
      Rails.application.routes.draw do
        scope constraints: AuthConstraint.new { |user| user&.dorian? } do
          mount Split::Dashboard, at: "split"
        end
      end
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-09-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-08-02
        • 2020-08-25
        • 2021-05-24
        相关资源
        最近更新 更多