Devise: authentication for lazy programmers

It has been a couple weeks since we first bloged about Devise. At that time, we released version 0.1 and now, after some great feedback, some enhancements and a few bugs fixes, we reached Devise 0.4. So, what changed since then?

I’m lazy, you’re lazy

Devise now comes with generators, so adding up authentication to your app is even easier and quicker to do. First, let’s install Devise if you haven’t yet:

gem sources -a http://gemcutter.org/
gem install devise

And let’s add it to your environment, all together with warden:

config.gem "warden", :version => "0.5.1"
config.gem "devise", :version => "0.4.1"

After setting the gem up, the first generator can be invoked:

script/generate devise_install

And it simply places an initializer at config/initializers/devise.rb. You can check there all devise configuration options, so the initializer fits well as documentation tool too. Some of the new things you can configure since 0.1 release is the :confirm_within period (the time the user can access the site even without confirming his account) and :remember_for period (the time the remember token is valid).

After we configured Devise, we are able create our models. And how hard can that be if we have a generator? So just do:

script/generate devise User

It’s going to create a model User, add map.devise_for :users in routes.rb and a migration file. And before we proceed, we just need to configure default_url_options for ActionMailer in config/environments/development.rb (the config below is for development, be sure to properly set them for test and production too):

config.action_mailer.default_url_options = { :host => 'localhost:3000' }

And have at least a route named root in our config/routes.rb (by default, devise will look for user_root_path, if none is defined, is uses root_path):

map.root :controller => "your_controller"

Now we just need to run migrations and we will be able to create our first user in the console:

User.create!(:email => "your@email.com", :password => "secret")

Now just start your web server and you will be able to sign your user in at /users/sign_in, request for another confirmation code to be sent, request a code to reset your password and so forth.

Just remember that Devise does not say anything about the sign up process, that’s why you have to create your users in console.

Customization

We also know that you want to customize your views, to use something like Formtastic instead of the default markup. Well, guess who is here to help you?

Generators! The command below will make a copy of all devise views to your application, including locale files, for flash messages configuration:

script/generate devise_views

Laziness for all!

We know that you are lazy and not just with ActiveRecord. You want to be lazy with Datamapper, Mongomapper, Couchrest… This is why we worked on making Devise a little bit more agnostic, all your ORM has to do is have an API similar to ActiveRecord (finder and callbacks mainly).

Besides, if you already travelled a bit on Warden world, you will see that there is a lot more than Devise, including some strategies for OAuth. So we are also working on making Devise compatible with such new strategies as well, that’s why you can already see a config.warden hook on the initializer.

Deprecations

Since things are getting really easy, we need to ask something back from you. Just watch out for to deprecations in Devise 0.4.0:

1) :authenticable is a typo, so we fixed that renaming it to :authenticatable. If you used Devise 0.3.x, you could see some deprecation warnings. However, in Devise 0.4.0 such warnings were removed. Tip: be sure to check your migration!

2) We had a notifier inside Devise called Notifier. We decided to follow Clearance convention and rename it to DeviseMailer. You will need to change your views from notifier to devise_mailer and your locale yml from notifier to mailer.

We hope you enjoy Devise as much as we do! And, as previously, we also have an example app in Github to help you get started too.

  • http://www.lamiscela.net Junio Vitorino

    Hi Plataformatec team, i’m very excited with Devise and firstly i’d like congratulate all involved in the project. I always want work with middlewares and with Devise now this is a bit possible. I’ve a doubt, Devise is ready for use in production mode?

  • http://www.lamiscela.net Junio Vitorino

    Hi Plataformatec team, i’m very excited with Devise and firstly i’d like congratulate all involved in the project. I always want work with middlewares and with Devise now this is a bit possible. I’ve a doubt, Devise is ready for use in production mode?

  • José Valim

    Devise is ready for production mode. We are using it on stage in a website yet to be launched, but there are already other devise users that launched their app with it.

  • José Valim

    Devise is ready for production mode. We are using it on stage in a website yet to be launched, but there are already other devise users that launched their app with it.

  • http://trevorturk.com Trevor Turk

    I’m curious as to why you’re choosing not to provide a sign up engine or generator. This is something I was looking for when I first tried devise out. Is there a 3rd party generator that you know of, or do you have plans to create one?

  • http://trevorturk.com Trevor Turk

    I’m curious as to why you’re choosing not to provide a sign up engine or generator. This is something I was looking for when I first tried devise out. Is there a 3rd party generator that you know of, or do you have plans to create one?

  • José Valim

    @Trevor, the reason we decided to not do “Sign up” because it’s something that needs to be customizable in a different way in almost all applications and we want to avoid controller configuration. We also use tools like Inherited Resources, which makes a controller with CRUD actions very very simple. So creating a sign up process is never trouble for us.

  • José Valim

    @Trevor, the reason we decided to not do “Sign up” because it’s something that needs to be customizable in a different way in almost all applications and we want to avoid controller configuration. We also use tools like Inherited Resources, which makes a controller with CRUD actions very very simple. So creating a sign up process is never trouble for us.

  • http://laguiar.wordpress.com/ Luiz Aguiar

    Valim, congratulations for the Devise, I’m looking close the project.
    Maybe it would be a good idea to publish an example of “sign up” form/route in the wiki page in the Github, it would help a lot to know how to do it the right way.

  • http://laguiar.wordpress.com/ Luiz Aguiar

    Valim, congratulations for the Devise, I’m looking close the project.
    Maybe it would be a good idea to publish an example of “sign up” form/route in the wiki page in the Github, it would help a lot to know how to do it the right way.

  • http://www.michaelbarton.me.uk Mike

    I was hoping you might have some plans to introduce open-id?

  • http://www.michaelbarton.me.uk Mike

    I was hoping you might have some plans to introduce open-id?

  • José Valim

    Hey @Mike, I’m also +1 on OpenID, but we are not going to implement it until we need it for an app we are working on. That can take one week or one year, we never know.

    But if anyone wants to implement it on top of Devise, he/she can count with my support. :)

  • José Valim

    Hey @Mike, I’m also +1 on OpenID, but we are not going to implement it until we need it for an app we are working on. That can take one week or one year, we never know.

    But if anyone wants to implement it on top of Devise, he/she can count with my support. :)

  • http://www.michaelbarton.me.uk Mike

    Ok, that’s understandable. I’ve been messing around with OpenID but I’ve found it pretty difficult to use compared with simple password authentication. The problem is specifically testing because you need some kind of real or mock OpenID server. This is not too bad in functional tests but when it comes to cucumber the tests become quite horrible to maintain – http://bit.ly/3h3AXb

  • http://www.michaelbarton.me.uk Mike

    Ok, that’s understandable. I’ve been messing around with OpenID but I’ve found it pretty difficult to use compared with simple password authentication. The problem is specifically testing because you need some kind of real or mock OpenID server. This is not too bad in functional tests but when it comes to cucumber the tests become quite horrible to maintain – http://bit.ly/3h3AXb

  • Pingback: Devise: flexible authentication solution for Rails | Plataforma Tecnologia Blog()

  • Brad

    I’m just a bit confused about the different roles in Devise. It seems for different roles, you just use a new model? So if I want a sign in page that any user can sign in, say editor, publisher, admin, super admin, I need to search through 4 tables for authentication? Is there not a better way to have many roles, each with their own permissions? I’m interested to start playing around with this!

  • Brad

    I’m just a bit confused about the different roles in Devise. It seems for different roles, you just use a new model? So if I want a sign in page that any user can sign in, say editor, publisher, admin, super admin, I need to search through 4 tables for authentication? Is there not a better way to have many roles, each with their own permissions? I’m interested to start playing around with this!

  • José Valim

    @Brad, you can use Devise with any authorization/roles library you like. The thing is Devise allows you to have two completely different models with the strategies you want. But if all your roles have a lot of behavior in common, I would recommend you to proceed as you suggest, using just one model.

    What happens at Plataforma is that, besides the end users, the client also wants to have an admin panel, so we prefer to do that using two different models, because they are totally unrelated.

  • José Valim

    @Brad, you can use Devise with any authorization/roles library you like. The thing is Devise allows you to have two completely different models with the strategies you want. But if all your roles have a lot of behavior in common, I would recommend you to proceed as you suggest, using just one model.

    What happens at Plataforma is that, besides the end users, the client also wants to have an admin panel, so we prefer to do that using two different models, because they are totally unrelated.

  • Brad

    any suggestions on what role libs might work well with devise? I agree about the admin/user differences, but I’m also interested in having a little more fine-tuned roles within users so they maintain a single login page, but have access to different sections based on their roles.

  • Brad

    any suggestions on what role libs might work well with devise? I agree about the admin/user differences, but I’m also interested in having a little more fine-tuned roles within users so they maintain a single login page, but have access to different sections based on their roles.

  • José Valim

    @Brad, we usually have a column named “role” and create some controller filters on top of that. I cannot recall a role library, but there is no reason any of them would be incompatible with Devise.

  • José Valim

    @Brad, we usually have a column named “role” and create some controller filters on top of that. I cannot recall a role library, but there is no reason any of them would be incompatible with Devise.

  • Jochen

    Hi,

    I managed to use Devise with Couchrest after a couple of changes in both Couchrest and Devise.

    However, I get the following error when using DeviseMailer:
    “undefined method `find_template’ for []:Array”

    Here is the backtrace after passing the “send_reset_password_instructions” action in “/devise_test/vendor/plugins/devise/lib/devise/models/recoverable.rb:38″

    ———-
    /usr/lib/ruby/gems/1.8/gems/actionmailer-2.3.2/lib/action_mailer/base.rb:581:in `candidate_for_layout?’
    /usr/lib/ruby/gems/1.8/gems/actionpack-2.3.2/lib/action_controller/layout.rb:240:in `pick_layout’
    /usr/lib/ruby/gems/1.8/gems/actionmailer-2.3.2/lib/action_mailer/base.rb:565:in `render’
    /usr/lib/ruby/gems/1.8/gems/actionmailer-2.3.2/lib/action_mailer/base.rb:552:in `render_message’
    /usr/lib/ruby/gems/1.8/gems/actionmailer-2.3.2/lib/action_mailer/base.rb:493:in `create!’
    /usr/lib/ruby/gems/1.8/gems/actionmailer-2.3.2/lib/action_mailer/base.rb:452:in `initialize’
    /usr/lib/ruby/gems/1.8/gems/actionmailer-2.3.2/lib/action_mailer/base.rb:395:in `new’
    /usr/lib/ruby/gems/1.8/gems/actionmailer-2.3.2/lib/action_mailer/base.rb:395:in `method_missing’
    ———–

    What do I have to change?

    Thanks for your help!

  • Jochen

    Hi,

    I managed to use Devise with Couchrest after a couple of changes in both Couchrest and Devise.

    However, I get the following error when using DeviseMailer:
    “undefined method `find_template’ for []:Array”

    Here is the backtrace after passing the “send_reset_password_instructions” action in “/devise_test/vendor/plugins/devise/lib/devise/models/recoverable.rb:38″

    ———-
    /usr/lib/ruby/gems/1.8/gems/actionmailer-2.3.2/lib/action_mailer/base.rb:581:in `candidate_for_layout?’
    /usr/lib/ruby/gems/1.8/gems/actionpack-2.3.2/lib/action_controller/layout.rb:240:in `pick_layout’
    /usr/lib/ruby/gems/1.8/gems/actionmailer-2.3.2/lib/action_mailer/base.rb:565:in `render’
    /usr/lib/ruby/gems/1.8/gems/actionmailer-2.3.2/lib/action_mailer/base.rb:552:in `render_message’
    /usr/lib/ruby/gems/1.8/gems/actionmailer-2.3.2/lib/action_mailer/base.rb:493:in `create!’
    /usr/lib/ruby/gems/1.8/gems/actionmailer-2.3.2/lib/action_mailer/base.rb:452:in `initialize’
    /usr/lib/ruby/gems/1.8/gems/actionmailer-2.3.2/lib/action_mailer/base.rb:395:in `new’
    /usr/lib/ruby/gems/1.8/gems/actionmailer-2.3.2/lib/action_mailer/base.rb:395:in `method_missing’
    ———–

    What do I have to change?

    Thanks for your help!

  • José Valim

    Someone had this same issue. Have you configured your ActionMailer (as asked in the README)? If yes, try searching the issues on Github or the mailing list.

  • José Valim

    Someone had this same issue. Have you configured your ActionMailer (as asked in the README)? If yes, try searching the issues on Github or the mailing list.

  • hassox

    For anyone who wants to implement OpenID, merb-auth, which was the pre-cursor to warden, has an open-id strategy that could be ported (and improved): http://github.com/merb/merb-auth/blob/master/merb-auth-more/lib/merb-auth-more/strategies/basic/openid.rb

    Just to help it along ;)

  • hassox

    For anyone who wants to implement OpenID, merb-auth, which was the pre-cursor to warden, has an open-id strategy that could be ported (and improved): http://github.com/merb/merb-auth/blob/master/merb-auth-more/lib/merb-auth-more/strategies/basic/openid.rb

    Just to help it along ;)

  • Pingback: Mmm…food » Authentication with Devise and Warden, part 1: Up and Running()

  • Jeem Khat

    Just started using Devise. A question – my login panel is on the home page (home/index). What’s the best way of configuring Devise so it redirects to this page when a login is required or when incorrect credentials are passed?

    I’ve tried adding the following routes after map.devise_for :users without success:

    map.new_user_session ‘home/index’, :controller => ‘sessions’, :action => ‘new’, :conditions => { :method => :get }
    map.user_session ‘home/index’, :controller => ‘sessions’, :action => ‘create’, :conditions => { :method => :post }

  • Jeem Khat

    Just started using Devise. A question – my login panel is on the home page (home/index). What’s the best way of configuring Devise so it redirects to this page when a login is required or when incorrect credentials are passed?

    I’ve tried adding the following routes after map.devise_for :users without success:

    map.new_user_session ‘home/index’, :controller => ‘sessions’, :action => ‘new’, :conditions => { :method => :get }
    map.user_session ‘home/index’, :controller => ‘sessions’, :action => ‘create’, :conditions => { :method => :post }

  • José Valim

    @Jeem, that was already asked in the mailing list, take a look there please:

    http://groups.google.com/group/plataformatec-devise

  • José Valim

    @Jeem, that was already asked in the mailing list, take a look there please:

    http://groups.google.com/group/plataformatec-devise