#20
Apr 18
Restricting Access
In this second part of the series on administration, you will learn how to lock down the site to keep the public from accessing the administration features.
<!-- episodes/index.rhtml --> <% if admin? %> <%= link_to 'New Episode', new_episode_path %> <% end %>
# controllers/application.rb helper_method :admin? protected def admin? false end def authorize unless admin? flash[:error] = "unauthorized access" redirect_to home_path false end end # episodes_controller.rb before_filter :authorize, :except => :index



Doesn't the before_filter need to return true in the other case in order to normally proceed the request?
Good question. It's not necessary because it continues as normal if it returns nil (which it will if the condition isn't met). The only time it stops is if it returns false.
flash[:error] does not work unless it is matched in the view layout, just in case anyone has issues getting the error message to show
I follow the tutorial but i can login even i type wrong password.
How to fix?
Hi i added the
<% admin? %>
<% end % >
it works great but when i combine it with the super simple authentication then the "must hidden" is not hidden.
any idea?
thanks
@ryan bates
hi, i already fix my error.. sorry i didn't see the "==" in the password for the password is equals equals.
now its working and my next step is to connect ito database when i have users table.
Thanks =)
If God would exists it will be you... very thanks for this screencast.
regards
hi ryan,
i was just wondering if you have idea where i can get a dummy's guide for different levels of authorisation.
like some people will be able to CRUD,
some write only, some read only.
i'm very new to RoR sadly
thanks in advance!
@jocelyn
I'd add a string "level" column to each user. In that you could save for e.g "Writer", "Reader", "Editor", "Admin", and others you need. Then when you just need to add some controls as you do for the admin area. For e.g.
if current_user.writer?
<show form to write>
end
and the writer? method would be like this:
def writer?
current_user.level == "Writer"
end
Be aware of the level, if the user can choose her level pay attention she don't select the Admin level.
I still have not resolved that question in my mind... if someones accesses a URL they should not, is redirecting the correct action?
I mean, it indicates your application will respond again and again to it.
On one project I did I simply determined to return a 404 (not found) when a protected resource was accessed. Indicating to the client they should not come back to that URI.
You got your thoughts on this dilemma?
@Jean, I think returning 404 is an excellent solution, especially if you have a User model setup. You can then fetch resources through the user model and rails will handle the 404 automatically for you. For example, let's say a User has many Projects and you only want the user to have access to his own project. In the controller show action you can do this:
current_user.projects.find(params[:id])
This way the user can only fetch the project he owns. If he doesn't own it, he will receive a 404.
@Jean and Ryan,
Strictly speaking, you _really_ should be returning a 403 in those cases. There *is* as a resource there, it's just forbidden to that user (or role, or what have you).
The simple way to do this is Rails is:
head :forbidden
Nick Kallen has shown a nice pattern[1] for doing this type of thing consistently across your app, using Rails' rescue_action method.
In reality you might want to override rescue_action_in_public instead -- check the API docs to get more of an idea of how these methods work, like how to make sure you can still render a custom error file.
Thanks for all the great Railscasts, Ryan.
[1] https://blabs.pivotallabs.com/users/nick/blog/articles/272-access-control-permissions-in-rails
great tips...
I added logged_in? to admin? to stop nil object errors...
def admin?
logged_in? && current_user.login == "admin"
end
woop...
I keep getting a major loop happening between the before_filter in my root controller...and the app controller authorize function, because if the filter chain is halted due to the admin not being logged in, the redirect is back to my root controller, which then calls the authorize function from the before filter...thus creating a loop...
so to remedy...this, from authorize
I redirect to the /sessions/new which is fine...but now every route /url is redirected there ... even though I have an :except in my before filter
any ideas?
cheers
dion
fixed...sorry for the spam
before_filter :my_authenticate , :except => [:index, :show]
Hey Ryan,
As always, your webcasts are exceptional. They've helped me out tremendously in all the Rails applications I've been working on.
Quick question... have you ever done any role-based access control? If so, maybe this could be a topic for one of your future webcasts?!
--
Thanks!
Will this still work for Rails 2.0 or is there a better way of doing it now?