问题
In my question How to have root view when user is not logged in rails? max answered that we can use authenticated
to make routes available only when someone is authenticated. I am having a probem that how can I structure this:
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
The problem is I don't want to allow any unauthenticated action on :subjects
how to stop that?
回答1:
If you want to limit access to subjects you should do it on the controller layer - not in the routes. Using before_action :authenticate_user!
will give a 401 Unauthorized
response and redirect to the sign in.
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
Using the authenticated
and unauthenticated
route helpers are useful when you want the have different responses for the same route for authenticated and unauthenticated users but is not how you should structure your application.
If you simply use authenticated
in your routes unauthenticated users will get a 404 Not Found response instead of being prompted to sign in. Which is not helpful.
Also resources :students, only: [:get]
does not generate any routes at all. The only
option is for limiting the actions (show, index, edit, update ...) not the HTTP method. Use rake routes
to see the routes in your app.
回答2:
Here is the simple way to structure authenticated and unauthenticated routes.
In app/controllers/application_controller.rb, add
"before_action :authenticate_user!"
.
My app/controllers/application_controller.rb file:
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
before_action :authenticate_user!
end
My 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
来源:https://stackoverflow.com/questions/43433717/how-to-structure-authenticated-routes-when-using-devise