如何在使用Devise时构建经过身份验证的路由?

时间:2017-04-16 04:30:31

标签: ruby-on-rails devise warden

在我的问题How to have root view when user is not logged in rails?中,我们回答说我们可以使用authenticated仅在有人通过身份验证时才提供路由。我正在探讨如何构建这个:

Rails.application.routes.draw do
  devise_for :users


  authenticated :user do
    # when authenticated allow all action on student
    resources :subjects do 
      resources :students
    end
  end

  # when not only allow read on student
  resources :subjects do 
    resources :students, only: [:get]
  end

  root "home#index"
end

问题是我不想在:subjects上允许任何未经身份验证的操作如何阻止它?

2 个答案:

答案 0 :(得分:3)

如果要限制对主题的访问,则应在控制器层上进行 - 而不是在路径中。使用before_action :authenticate_user!会提供401 Unauthorized响应并重定向到登录。

class ApplicationController
  # secure by default
  before_action :authenticate_user!, unless: :devise_controller?
end

class SubjectsController < ApplicationController
  # whitelist actions that should not require authentication
  skip_before_action :authenticate_user!, only: [:show, :index]
  # ...
end
Rails.application.routes.draw do
  devise_for :users

  resources :subjects do 
    resources :students
  end

  root "home#index"
end

如果您希望对经过身份验证和未经身份验证的用户使用相同路由的响应不同,则使用authenticatedunauthenticated路由助手非常有用,但不是应该如何构建应用程序。

如果您只是在路线中使用authenticated,未经身份验证的用户将获得404 Not Found响应,而不是提示您登录。这对您没有帮助。

同样resources :students, only: [:get]根本不会产生任何路线。 only选项用于限制操作(显示,索引,编辑,更新...)而不是HTTP方法。使用rake routes查看应用中的路线。

答案 1 :(得分:0)

以下是构建经过身份验证和未经身份验证的路由的简单方法。

在app / controllers / application_controller.rb中,添加 "before_action :authenticate_user!"

我的app / controllers / application_controller.rb文件:

class ApplicationController < ActionController::Base

protect_from_forgery with: :exception

before_action :authenticate_user!
end

我的config / routes.rb:

Rails.application.routes.draw do
  devise_for :users
  root "home#index"
  devise_for :users, controllers: {
                       :sessions => "users/sessions",
                       :registrations => "users/registrations" }
  authenticated :user do
      resources :students
  end



unauthenticated :user do
  #Some route
  end

end