#160 Authlogic
May 04, 2009 | 14 minutes | Plugins, Authentication
Authentication can get very complex. In this episode I show how Authlogic can handle this complexity while you stay in control of how it is presented to the user.
- Download:
- source code
- mp4
- m4v
- webm
- ogv
Authlogic is pure awesomeness - using it in few projects already and I'm very satisfied. Also check other very elegant plugin from BinaryLogic - searchlogic
@Vidmantas : thanks for the tip!
BinaryLogic's plugin are awesome ;)
@Pierre : I agree. BinaryLogic's code is very clean and well thought out. I've learned a lot looking through it.
Authlogic has been my go-to plugin for authentication for the past few months. The only thing it was missing were some examples on the web to help ease the learning curve, especially for those who don't usually dive into the source. Thanks Ryan for the screencast.
Authlogic rocks. Thanks for the tutorial, it will be helpful to explain why we chose authlogic to our users. I would also suggest that you consider a screencast on Ben's very awesome searchlogic.
How do you do authorization from AuthLogic, if possible? If not, is there a good role-based authorization solution that works with AuthLogic?
I second @Mark on the roles
Ryan, would you mind explaining the edit_user_path(:current) syntax? I've never seen :current passed into a restful route helper before and I didn't see anything in the Rails docs.
Authlogic is the shit. Before I found it I used restfull_authentication (as probably almost everyone did).. but authlogic is just a better, cleaner sollution. As an extra bonus the coder BinaryLogic seems superpicky about his code.
Ppl should also check out:
http://www.binarylogic.com/2009/03/30/authlogic-2-0-with-some-openid-goodness/
.. and..
http://www.binarylogic.com/2009/02/25/the-future-of-authlogic-add-ons/
.. just think about it, soon you might be able to offer facebook connect authentication in your apps without alot of extra code.. cause of authlogics awesomeness :)
@Mark, @Jose, Authlogic only handles authentication, not authorization. It is important to draw the line there because there are *many* authorization techniques. You may need just an "admin" column in the user model, or a full blown role based complex permission system. Authorization usually has little overlap with authentication logic.
I do plan to cover some more authorization techniques in future episodes. The beauty is that it will work with pretty much whichever authentication scheme you are using.
I can't say enough good things about Authlogic. I never liked RA and dreaded having to unearth it for nearly every project. For me, Authlogic brought back the joy in starting a new rails app.
Why, you ask. Simply... it walks, talks, and smells like rails. RA is more like you multi-challenged uncle sporting the latest hair replacement product.
Thanks Ryan! Authlogic is really excelent! For those who need to build account confirmation or reset password on top of Authlogic, check out the AuthHelpers plugin (http://github.com/josevalim/auth_helpers)!
The idea of the plugin is to hold modules that are not handled by Authlogic by default. So those who wants an authorization system, would consider building it on top of AuthHelpers, so you will have to do it just once!
Seriously what's up with the :current thing?
@jared, @andy: The :current is just a arbitrary symbol. Instead of passing an id the string "current" is used in the url. This does not make a difference since params[:user_id] is not used in the controller. Still it makes for a nice urls, since you can tell that you are editing the current user.
Hope that helps.
Great Video! Congrats, Ryan. It would be marvelous if you show some authorization techniques. I was just enthusiastically waiting for your Authlogic video and I'm waiting now for the authorization rules :) Thank you very much!
Great cast Ryan. I started using authlogic last week and love it.
One problem I keep coming across in my apps is how to keep normal users viewing their own records and the various administration levels viewing what is available to them. It would be great if you could share your thoughts on keeping authorization systems clean and simple. Maybe by re-factoring much of the code to a gem/plugin?
Something like this everywhere gets tedious and dirty:
if admin?
@post=Post.find(params[:id])
elsif moderator?
@post=...
else
@post=...
end
Just one remark:
it is not a good idea to show a user in the login validation that only the password is wrong. would be better if "username or password" is wrong is displayed.
But this can be easily added and I think this was just a "to less time to secure all things"-thing for this small but good example of authlogic.
Nice as always, thanks, another cast with advanced use of Authlogic would be great.
Something like reset\change password, or a basic role system :)
@mark, @jose, @ryan check out acl9 on github, it works great with Authlogic.
I would love a screencast on Roles. This is a great screencast as usual Ryan. Thanks for all your work.
Cucumber testing with Authlogic would be great for RC#161!
Installing Authlogic as a gem is plain stupid, plugins are much better than gems to work with a Rails app. Everybody wants gems and then they go through the pain of vendoring them...
I don't really see the benefit of Authlogic over Restful_auth which isn't that intrusive.
Thanks Ryan for the screencast. I am glad to find an RA alternative.
i get undefined method `title'. what is this 'title' anyway?
I stumbled across authlogic just a few days ago, then all of a sudden this pops up. Great screencast, can't wait to try it out for a project I'm starting!
This plugin helped me a lot past few weeks when I by chance stumbled upon it as well. As I haven't been using RA due to the lack of customization this is really neat.
Thanks for the great Screencast.
Authlogic is working for me pretty good. However I am not able to get the documentation how to create a valid users.yml for functional testing. Any hints for me?
Authlogic is awesome. Now if we could get a railscast that integrates authlogic with rails-authorization-plugin (http://github.com/DocSavage/rails-authorization-plugin/tree/master)... That would be fantastic!
Yeah gotta thank you for this and nifty generators :)
This looks really good.
I like to test first and add functionality as I go, just ended
up deleting and rewriting a lot of RA.
My only question is does it offer the same level of security as RA,
hashing strength etc?
Apologies for going off topic but how do you get the syntax highlighting on the page?
thanks for this, i was actually working on a app requiring this functionality not long ago but the whole authorisation thing with Restful_Authentication is so old; glad this gem freshens it up.
majorly glad all the core code doesn't go into my app, makes it a lot more cleaner.
Appreciate it
Hey Ryan,
Thanks for another great episode, but i'm having a couple if issues with Authlogic and nifty-generators. I followed your instructions on how to install nifty-generators and authlogic, but everytime i try to run nifty_scaffold i get this.
Missing these required gems:
authlogic
You're running:
ruby 1.8.6.114 at /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby
rubygems 1.3.1 at /Users/john/.gem/ruby/1.8, /Library/Ruby/Gems/1.8, /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/gems/1.8
Run `rake gems:install` to install the missing gems.
i've run rake gems:install and still nothing. when i comment out config.gem 'authlogic' and run it then i get:
Couldn't find 'nifty_scaffold' generator
I'm guessing it's a $PATH issue. i have gem in /usr/local/bin and everything else (rails, rake, etc) in /usr/bin
any ideas?
Thanks,
John
shouldn't the 'user_sessions' be 'user_session' and the route 'resources' be 'resource'?
definitely RA is uglier but at least you can customize what you don't like, and some features of authlogic don't amuse me at all. for instance, the brute force block comes to action if you try a username for more than a limit number of times. in my opinion this should be based on the IP, because 1) someone have more space to try a common password to all usernames and 2) someone can send a lot of requests until all usernames get blocked.
I'd love to see an Authlogic + acl9 + Cucumber demo!
Simple problem:
The following liine through an error.
<!-- user_sessions/new.html.erb -->
<% title "Login" %>
Undefined method. I guess title is a helper method? But nowhere defined.
Any help appreciated
Jens
What would i need to change to store the session-data in the db?
Jens, you need to run Ruby script/generate nifty_layout before running nifty_scaffold. nifty_layout generates the title helper.
Michael, thanks a bunch that worked like a charm.
Without dealing with roles how useful is this?
Ryan, I cant even begin to tell how much your casts have improved my career. Thank you.
I have been having an issue with AuthLogic not destroying the session and sometimes logging in automatically on certain actions.. After researching a little on the google groups, they talk about changing the session to the active record store instead of cookies as they talk about rails cookies not being a very good solution. Im not quite sure how to make these changes in AuthLogic, and still havent come across any discussions(yet) on it. Maybe something to discuss or add to the show notes etc...?
any advice would be great
Thanks Ryan
To those having trouble with the title helper method error:
check out app/helper/layout_helper.rb in the example source
Thanks Ryan for this wonderful Screencast!
Please u can make a screencast with Authlogic + Role based Authorization !
Great Job!!!
Got the "register | login" working great on my site, until I added before filter to each controller to require a logged in user (following the example from the authlogic/github tutorial) Now, when logged in user, views show as expected, but "current_user" is nil causing the "edit profile | logout" code to be ignored, and the "register | login " to display, however I have a current user object or the view would not display??? newbie needs help.
Can you login with either a username or password?
What I mean by the above is you can put a login or email address in to one field along with your password in a different field.
Hey, Ryan, thanks for being my 2nd tutor in Rails :)
When changing password to crypted_password we're breaking the test's fixtures, so make sure to check those!
Ryan,
you might want to use singular resources for manipulating current_user, so that you don't have to pass in :current and such to edit_user_path. Perhaps you're aware of this and didn't want to mention too many different things in the screencast, but I thought it was worth mentioning anyways.
Awesome railcast Ryan.
I too am eager to learn an authorization overlay on authlogic - at the minimal I would like to add admin status to some of the users.
great cast and really useful plugin.
however I wonder if you checked the single_access_token feature.. i am trying to work with it but it seems that i have something wrong in configuring it to work with all requests.
many thanks
Hey everyone, I'm a complete beginner at ruby and rails and was wondering how you can access the username or email address of an existing user object without using the a form construction.
I attempted something along the lines of:
<% for user in @users %>
<tr>
<td><%=h user.name %></td>
<td><%=h user.email %></td>
</tr>
<% end %>
but clearly the user object doesn't have methods like name or email. Are there methods for getting these, or does this require a completely different strategy. Sorry if this question is too basic.
I'm getting errors like the following:
undefined method `name' for #<User:0x722b080>
For me, the current_user and current_user_session controller methods work only in the development environment. When controllers are kept in memory across requests (as in production or test environment) the @current_user_session variable gets assigned once and is never updated, making it impossible to log out or switch to a different user. Is anyone else having this problem? Am I missing something?
Thanks, Ryan, for another fantastic episode. Authlogic has really cleaned up my apps.
Ignore my previous question. I was working on some code simultaneously and got confused... great cast Ryan.
Alex Reisner, take a look at "Session bugs".
http://rdoc.info/projects/binarylogic/authlogic
It's because of Passenger. Bring your sessions into database, and then everything will work fine!
Hope it helps
Hey guys, I'm getting a:
undefined method `record' for #<User:0xb68aa708>
error. Is this cause I'm on Rails 2.2.2 still?
/usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/attribute_methods.rb:260:in `method_missing'
btw - awesome screencast as usual!
Thanks!
Some asked about the :current argument passed to edit_user_path. It is used in the URL.
See http://api.rubyonrails.org/classes/ActionController/Routing.html and scroll down to Named Routes.
In this same example, if you replace
edit_user_path(:current)
with
edit_user_path(current_user.username)
Then the URL will be something like
http://localhost:3000/users/ryanb/edit
Everything works except I'm getting "ActionController::InvalidAuthenticityToken" when I try to login. I have uncommented the 'secret' in application.rb
never mind - my environment.rb needed to have config.action_controller.session_store = :active_record_store
uncommented
Still didn't explain what UserSession is all about.
I still dont understand where it creates the user_sessions database...
I followed the screencast and i still get :
Showing app/views/user_sessions/new.html.erb where line #7 raised:
undefined method `username' for #<UserSession: no credentials provided>
I have run the script/renerate session... and script/renerate nifty_scaffold with --skip-model...
Any ideas?
I'm getting a similar problem to John:
$ sudo gem install nifty-generators
Password:
Successfully installed nifty-generators-0.2.4
1 gem installed
Installing ri documentation for nifty-generators-0.2.4...
Installing RDoc documentation for nifty-generators-0.2.4...
$ script/generate nifty_scaffold
no such file to load -- nifty-generators
...
Missing these required gems:
nifty-generators
You're running:
ruby 1.8.6.287 at /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby
rubygems 1.3.4 at /Users/robert/.gem/ruby/1.8, /Library/Ruby/Gems/1.8, /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/gems/1.8
Run `rake gems:install` to install the missing gems.
Any clues?
Solved:
comment out environment.rb entry , config.gem "nifty-generators" once rake gems:install executed.
Weird.
As "michael" pointed out, Ryan forgot to mention that you should run "script/generate nifty_layout" to get the layout stuff.
after I change the environment.rb and restart webrick I receive the following error
/usr/lib/ruby/1.8/rubygems.rb:149:in `activate': can't activate activesupport (>= 0, runtime), already activated activesupport-2.1.0 (Gem::Exception)
if anyone has any ideas let me know, if not I will try and return with a fix.
NOTE:
using current_user helper in the layout will hit the database and fetch the user record for every request from logged in user.
Use It Wisely!
I wonder how this should work:
UserSession.find
as find needs an ID, at least I always get "Couldn't find UserSession without an ID" if I try that. UserSession.first works though (returns nil in case no session was found)
?
might want to add to the command line text that to create the application.xxx and layout_helper files you need to do the following command first. otherwise the 3 files are missing.
script/generate nifty_layout
Layout: app/views/layouts/application.html.erb
Stylesheet: public/stylesheets/application.css
Helper: app/helpers/layout_helper.rb
In the current_user method in the app_controller there is this line: @current_user = current_user_session && current_user_session.record
What does current_user_session.record do? I've checked the documentation and searched through the source but I'm no clearer. My gut instinct says that it is probably updating last_requested_at but I'd like to know for sure.
Cheers
Any updates from anyone re best Authorization approach to mesh in with authlogic?
It would be nice to see how to integrate Lockdown with Authlogic.
In Rails 2.3.4 it says: undefined method `password_confirmation' for #<User:0x7f4ffda0a7e0>
I added an
attr_accessor :password_confirmation
to the User-Model
But still got the Error:
Password confirmation is too short (minimum is 4 characters)
Nice episode, but this spam is really annoying :(
Add some captha please
I'm trying to alter the code so that an "comment" is automatically associated with the "user" that created it. I was able to associate an article with its creator, but when I tried the same process for comments, I get a nil error on the user when I access comment.user.username.
----------------Steps--------------
1)To the migration script I added: "add_column :comments, :user_id, :integer"
2) To comments.rb I added: "belongs_to :user"
3) To user.rb I added: "has_many :comments, :dependent => :destroy"
4) To comments_controller.rb I added: "@comment.user = current_user" to the "new" method
4) To app/views/comments/_form.html.erb I added: "<%= f.hidden_field :user_id %>"
5) To app/views/articles/show.html.erb I add: "<%=h comment.user.username %>" to access the username of the poster.
----------------------------------
However I get an error from step #5
Clearly comment.user is not being set, when I create a new comment but I don't understand what I am doing wrong because these are the same steps that were used to automatically to a assign a comment to its article, and an article to the user?
To everyone having the same problem I had, that is, at no time the table for sessions was created in the db and I kept having this [not so clear] error: "no credentials provided" when trying to login. You should just create the table. Or at least this did the trick for me:
/db/migrate/migration2.rb
class CreateSessions < ActiveRecord::Migration
def self.up
create_table :sessions do |t|
t.string :session_id, :null => false
t.text :data
t.timestamps
end
add_index :sessions, :session_id
add_index :sessions, :updated_at
end
def self.down
drop_table :sessions
end
end
ps: it might sound lame, but everyone should get the chance to start from the scratch...
I am running into this error code with the password confirmation.
"authlogic password confirmation is too short"
Has anyone experienced this error? I need your help.
Thanks in advance for your help.
You may want to have a look at the Authlogic Generator which generates the basic code from Bens tutorial (with test coverage).
http://github.com/masone/authlogic_generator
Support for rspec and haml.
I followed it step by step and when in the minute 6, when I click on "submit" button I receive this error:
undefined local variable or method `persistence_token' for #<User:0x104203500>
What is wrong? :S
Something like reset\change password, or a basic role system :)
I got the "password confirmation is too short problem"
and corrected it by adding
attr_accessible :password, :password_confirmation
in the user model.
Is this the correct solution?
Anyone help with:
Q1: What do you have to do in all your other controllers & models (i.e. besides user & user_session)? Do you need to put something like "before_filter :require_user" at the beginning of other controllers? (or should something like this go in application_controller to get blanket coverage)
Q2: Can anyone confirm what config exactly is required to make the one time password (persistence_token) work?
thanks
Hello.
For those that are having the :password no method error.
Check out your migrations. Verify you don't misspelled the columns.
Cheers!
If you need authorization please see episode 188...
Just did a tutorial on password resets in Authlogic: http://github.com/rejeep/authlogic-password-reset-tutorial
And another mention for authlogic with roles screencast! Thanks!
Realy a great cast !
Why not updated your cast #124 (Beta invitation) for authlogic ? :)
And what's about a other onem "How to add a validation email for authlogic" ? Would be great.
So any way, thanks a lot for your cast !
I get : Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id.
I can't find how solve this problem.
Hey, I love your site, and the tutorials are so helpful.
I'm trying to implement this project, but I'm running into error after error. I'm just a newbie, could you help me?
Here's the error I'm currently stuck on:
Authlogic::Session::Activation::NotActivatedError in HomepageController#home
You must activate the Authlogic::Session::Base.controller with a controller object before creating objects
Any suggestions?
@zizo: whatever object you're calling is nil, try adding something like:
@user = User.new
to your controller. That helped me when I had the same error with my @user object.
Can I make the password field optional?
Hi,
Im creating my first Rails project and Im having a problem with
Authlogic. I need to have a User with specified name, surname, etc.
(and of course essential Authlogic fields). Is it possible to create
one migration with mentioned additional fields and those from
Authlogic?
Thanks.
To anyone that's having problems with this tutorial:
THIS IS OLD. Authlogic has changed and this tutorial will no longer get you where you need to be.
Go here instead:
http://github.com/binarylogic/authlogic_example
I dont understand how it gets to the create action
for example I changed my root as follows
map.root :controller => "users", :action => "new"
so it goes straight to the page where a new user can be entered. once the user hits submit, it goes back to the controller, but how does the controller know that it should go to the create action next?
The reason I ask is because instead of going to create action directly, I want it to go to another form with more parameters (city, country etc)
Thanks for the example!
@chetu - Why would you do that? If you only need to track which userid you currently want to assume, then why not just put the user into the ession - and be finished. Just because you have a golden hammer (authlogic), does not mean everything is a nail. ;-)
I was very impressed * with tutorials that you serve, feel very fortunate to be able to visit your site
For anyone having problems with Rails 3:
ActionView::Template::Error (undefined method `to_key' for #<UserSession: no credentials provided>)
this fixed the problem for me:
class UserSession < Authlogic::Session::Base
# Fix
include ActiveModel::Conversion
def persisted?
false
end
# End of fix
end
The idea of the plugin is to hold modules that are not handled by Authlogic by default. So those who wants an authorization system, would consider building it on top of AuthHelpers, so you will have to do it just once!
"Session is not a valid generate script"
problems with logging in...
screencast got me to where I can create users without a problem. But I can't get it to create a session. I am using a form that sends data to the server via an Ajax request (this may change, but for now I have to do it this way).
Looks like :
<% form_remote_tag :url => {:controller => "user_sessions", :method => 'post'} do -%>
<%= text_field_tag "user_session[email]", "email you registered with", :class => "messageTextField"%>
<%= password_field_tag "user_session[password]", "", :class => "messageTextField"%>
<% end %>
I can see the data coming in as :
Processing UserSessionsController#create (for 12.13.14.15 at 2010-10-04 22:42:17) [POST]
Parameters: {"commit"=>"DONE", "user_session"=>{"password"=>"campaign", "login"=>"myemail@gmail.com"}, "method"=>"post"}
And confirm that the user exists and the credentials are right. The code processing it is :
def create
@user_session = UserSession.new(params[:user_session])
msg = (@user_session.save) ? "success" : "failure"
if request.xhr?
render :update do |page|
page.alert(msg)
end
return
end
end
and it's not working...
Following up : there doesn't appear to be a point when a DB table for the sessions is created anywhere in the screencast. Where does that happen?
Ryan, why didn't you use ||= in current_user and current_user_session?
seconding juliamae's comment. this looks old if you're using rails 3.
The "Rails 3 Way" book has a chapter on authlogic.
seconding juliamae's comment. this looks old if you're using rails 3.
"Rails 3 Way" has a chapter on authlogic.
For quick login into system:
https://github.com/igorkasyanchuk/any_login
Support Authlogic and other auth gems.
Please give it a try!