Assuming that I'm not signed in.
In this case, it displays this flash notice when accessing to actions in mails_controller.
You need to sign in or sign up before continuing.
However, it won't display in communities_controller.
Why? and How can I fix?
mails_controller.rb
class MailsController < ApplicationController
before_filter :authenticate_user!
....
end
communities_controller.rb
class CommunitiesController < ApplicationController
load_and_authorize_resource :find_by => :id
before_filter :authenticate_user!
end
try moving the load_and_authorize_resource line after the before_filter. The load_and_authorize_resource line will raise an exception when it can't find the resource for member actions which may be happening before you even get to the before_filter line
Related
I want one pages of my ruby on rails web application inaccessible to one of my STI model types. I have two models typeA and typeB inheriting from User. I have used the column type in the User table to implement STI. I am using Devise gem for User sessions. I want one webpage 'http://localhost:3000/rate' inaccessible to my typeA User. Whenever an User logs in who is of the type 'typeA', he does not have the option of seeing the link 'Rate'. But I also do not want him to be able to access that page by the link 'http://localhost:3000/rate'. If he tries to access it through that link, I want to sign him out and make him log in again.
I managed this by using a piece of code in my Controller with the specific method for 'rate'.
def rate
if current_user.type == "typeA"
sign_out(current_user)
redirect_to new_user_session_path
else
#Code for User of typeB
end
end
This is working but I wanted to know if this can be done in a better way using before_filter :authenticate_user! or something else
Right now my before_filter part looks like this
before_filter :authenticate_user!, except: [:index, :show]
Is there any way I can make a change to the upper code to achieve that functionality.
P.S: Maybe this can be done better if I had used roles or other gems like CanCan/Pundit but I do not have much time left to submit my project, so I do not want to get into all that right now.
you can add another before_filter on the controller you want to restrict the access just to confirm your STI user type without overiding devise's authenticate_user! filter.
application_controller.rb
class ApplicationController < ActionController::Base
def confirm_user_type(user_type)
redirect_to new_user_session_path unless current_user.is_a?(user_type)
end
end
pages_controller.rb
class PagesController < ApplicationController
# must be authenticated to access
before_filter :authenticate_user!
# must be user of TypeA to access
before_filter { |c| c.confirm_user_type(TypeA) }
def rate
...
end
end
Then, you can use the same filter before_filter { |c| c.confirm_user_type(TypeB) } for STI user type: 'TypeB'
Try this:
class ApplicationController
before_action :authenticate_user!
def authorize_user!
if current_user.type == "typeA"
sign_out(current_user)
redirect_to new_user_session_path
end
end
end
with your controller:
class SomeController < ApplicationController
before_action :authorize_user!, except: [:index, :show]
def top_secret
...
end
end
I believe if a before_action (the new name for before_filter) renders or redirects, the action won't be processed.
I want to use authenticate_user! in all, but a single page "login" page, in my Rails application. For this I can insert authenticate_user! in all the controllers. But it'd be easier to insert it into ApplicationController and
disabe only on "login" page or rather in SessionController for "login" action. Is it possible?
Yes, you can do.,
class ApplicationController
before_filter :authenticate_user!
end
class SessionsController < ApplicationController
skip_before_filter :authenticate_user!
end
And you can mention the methods you want to exclude using except:.
I am setting up a very simple rails app that involves a simple authentication check before you can enter the site. But, when the before_filter runs, and the user is redirected to the login path, a redirect loop occurs.
ApplicationController:
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
before_filter :check_session
private
def check_session
redirect_to login_path and return unless current_user?
end
def current_user?
!session[:username].blank?
end
end
SessionsController
class SessionsController < ApplicationController
def new
end
end
The issue is that, since your SessionsController inherits from ApplicationController, it actually inherits the before_filter as well. This means you are not allowing someone to see the login page unless they are logged in, which is usually undesirable behavior. You want to skip this before_filter on the login page:
class SessionsController < ApplicationController
skip_before_filter :check_session, only: :new
def new
end
end
I think you have problem in your routes. One way of solution is defining a root path for your app as:
root 'app_entry#index'
Then create a controller for it as given below:
class AppEntryController < ApplicationController
def index
if current_user
redirect_to 'controller_name/action_name'
else
redirect_to '/users/sign_in'
end
end
Hope this helps you.
You should use the before filter like this
before_filter :check_session, :except => [:new]
I'm trying to make the user profiles in a project I'm working on viewable by anyone on the web, so I tried adding skip_authorize_resource :only => [:show] to the user controller and the user model. However, when I visit /users/1 nothing happens and I'm prompted to login when I add it to the controller; when I add it to the model, i get an error message:
undefined method `skip_authorize_resource'
I think you can use authenticate_user method for devise
skip_before_filter :authenticate_user!, :only => :show
or you can use
check_authorization
method in controller
like this way
class ApplicationController < ActionController::Base
check_authorization :unless => :do_not_check_authorization?
private
def do_not_check_authorization?
...
end
end
I am trying to require login on all pages on my Rails 4 web site.
In the ApplicationController I have added before_action :authenticate_user!, but it simply doesn't do anything. I have tried to add the same before_action :authenticate_user! to another controller, and it works fine.
Do I need to do something else to the ApplicationController, to make the login be required on all actions (Except signup/signin)?
Here's the actual code we use:
#app/controllers/application_controller.rb
Class ApplicationController < ActionController::Base
#Actions
before_action :authenticate_user! #-> routes to the login / signup if not authenticated
end
The problem you probably have is two-fold:
--
Make sure your other controllers are inheriting from application_controller:
#app/controllers/other_controller.rb
Class OtherController < ApplicationController
...
end
--
You're somehow "skipping" the before_action callback
If you're using skip_before_action anywhere, you need to remove it. It will likely cause a problem with your authenticate_user! method. To fix this, I would firstly test without any skip_before_action callbacks, and then see what gets it working correctly
A further note - signin / signup won't matter. They all inherit from the Devise controllers; they'll just run as required.
UPDATED 2019
In your routes.rb file you may have mentioned only authenticated_user path like below
authenticated :user do
root to: 'home#index', as: :root_app
end
You should mention unauthenticated_user path too to make it work or just root path without unauthenticated_user or authenticated_user