#209
Apr 12, 2010

Introducing Devise

Devise is a full-featured authentication solution which handles all of the controller logic and form views for you. Learn how to set it up in this episode.
Download (32.2 MB, 10:36)
alternative download for iPod & Apple TV (26.8 MB, 10:36)

Resources

bundle install
rails generate devise_install
rails generate devise User
rake db:migrate
rake routes
# Gemfile
gem 'devise', '1.1.rc0'

# config/environments/development.rb
config.action_mailer.default_url_options = { :host => 'localhost:3000' }

# models/user.rb
class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :token_authenticatable, :lockable, :timeoutable, :confirmable and :activatable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  # Setup accessible (or protected) attributes for your model
  attr_accessible :email, :password, :password_confirmation
end

# migration
class DeviseCreateUsers < ActiveRecord::Migration
  def self.up
    create_table(:users) do |t|
      t.database_authenticatable :null => false
      # t.confirmable
      t.recoverable
      t.rememberable
      t.trackable
      # t.lockable :lock_strategy => :failed_attempts, :unlock_strategy => :both

      t.timestamps
    end

    add_index :users, :email,                :unique => true
    # add_index :users, :confirmation_token,   :unique => true
    add_index :users, :reset_password_token, :unique => true
    # add_index :users, :unlock_token,         :unique => true
  end

  def self.down
    drop_table :users
  end
end

# migration
create_table(:users) do |t|
  t.database_authenticatable :null => false
  # t.confirmable
  t.recoverable
  t.rememberable
  t.trackable
  # t.lockable :lock_strategy => :failed_attempts, :unlock_strategy => :both

  t.timestamps
end

add_index :users, :email,                :unique => true
# add_index :users, :confirmation_token,   :unique => true
add_index :users, :reset_password_token, :unique => true
# add_index :users, :unlock_token,         :unique => true
<!-- layouts/application.html.erb -->
<div id="user_nav">
  <% if user_signed_in? %>
    Signed in as <%= current_user.email %>. Not you?
    <%= link_to "Sign out", destroy_user_session_path %>
  <% else %>
    <%= link_to "Sign up", new_user_registration_path %> or <%= link_to "sign in", new_user_session_path %>
  <% end %>
</div>

RSS Feed for Episode Comments 54 comments

1. Gregor Apr 12, 2010 at 03:03

finally! Waited the whole morning for your railscast ;-)


2. Art Apr 12, 2010 at 03:12

me too :)


3. Michael van Rooijen Apr 12, 2010 at 03:30

I've used Devise once pre-1.0 and am using it again with the current version. (Currently on a Rails 2.3.5 application) and I must say it is one of my favorite authentication solutions. It's easy to understand and set up, plus it provides most of the common real world solutions out of the box in the form of modules, so *most* of the time you're practically done with the base setup and all you need to do is style the views. Also good to note is that it supports other ORM's as well, not just ActiveRecord, and you can build your own custom modules if needed.

Definitely recommend to try out this authentication solution if you need one!


4. Boris Barroso Apr 12, 2010 at 04:36

Thanks for the episode I will need to update some parts of my blog post in (Spanish). http://www.boliviaonrails.com/2010/04/05/como-usar-devise-con-rails-3/


5. purab kharat Apr 12, 2010 at 04:44

Already in Rails making good authentication is really easy But I think with Devise plugin. authentication is became more easy..


6. Omar Joseph Qunsul Apr 12, 2010 at 05:44

Pretty nice ... I liked this one


7. dickstar Apr 12, 2010 at 07:15

Thank you.
May you introudce the access control plugin?
Because there are so many authentication solutions now. But no easily operated access control to use.
Always need to use keyboard. Is there any good UI for access control without typing?


8. elad Apr 12, 2010 at 07:46

Thanks Ryan, This screencast is very useful as always..

Can you please advise which one to use when:
1. nifty_authentication (yours)
2. Authlogic
3. Devise

I don't mind creating my own logic for Authlogic, you show us how to do that in chapter 160 :), just looking for the best solution out there, what would you use?
many thanks...


9. Authentication with Subdomains Apr 12, 2010 at 09:06

Thanks for putting the spotlight on Devise.

I put together a Rails 2.3 example app (with a walk-through tutorial) that shows how to set up Devise with subdomains: http://github.com/fortuity/subdomain-authentication (click above for the link). For anyone who needs a quick start for blog-style subdomains in Rails.


10. Ryan Bates Apr 12, 2010 at 09:25

@dickstar, are you referring to acl9? I'm not a fan of that solution and prefer something like Declarative Authorization (episode 188) or CanCan (episode 190).

@elad, I only recommend nifty_authentication if you want a very minimal starting point and want to add most of the authentication from scratch without any external dependencies. The other solutions are quite complicated and sometimes writing from scratch is easier if you have very custom needs.

Authlogic is the next step up, where you are writing the controller and views from scratch but the authentication logic is handled for you. This is great if you want to customize that behavior extensively.

Devise is the full stack which means it does most of the work for you. It provides many features such as password resetting which you don't see in the others. If you want a really complete solution and don't need to customize it extensively then this is a good way to go.


11. Soleone Apr 12, 2010 at 10:08

Hm, I heard some guys were very opposed to Devise/Warden. The argument was that authentication should be on the model layer (like the user model), instead of being intercepted at the middleware level.

I'm curious what people think about this and if it might be a valid concern!


12. doon Apr 12, 2010 at 10:09

Thanks for this. Just starting a new Rails 3 project and was going to look at Devise (to replace authlogic I've used previously.). So your timing is impecable...


13. BradM Apr 12, 2010 at 11:31

I just so happened to find Devise last week and I was particularly interested in the Subdomain tutorial (Linked above).

I understand that you will be getting into manipulating Devise such as changing the views etc, but I think it may be beneficial to the community (and Devise) if there was a tutorial based on 'Basecamp-style-Account-Subdomains'

Where is User under a specific account/subdomain security type model.

BTW, great work! My Monday mornings have become Railscasts and Tim Horton (Best Coffee in Canada) type of mornings.


14. Javi Apr 12, 2010 at 12:39

Hi, Ryan.

I think on this page the migration code has been pasted twice, right?

BTW, just curious: why don't you like confirmation emails for registration?


15. Henrik Hodne Apr 12, 2010 at 12:51

Amazing, I just tried to get this working yesterday :P


16. Ryan Bates Apr 12, 2010 at 12:56

@Soleone, I'd be interested in reading a more detailed article on the practical reasons against handling authentication in Rack middleware. MVC is a great principle, but it should not be followed blindly.

@BradM, subdomain handling has changed a little in Rails 3 so I'll likely be covering it in a future episode. However I don't consider it to be specific to a given authentication solution. You can apply my existing subdomain screencast (episode 123) to the Basecamp style. Just replace blogs there with projects.


17. Kurt Werle Apr 12, 2010 at 13:04

Gotchas:
If you already have a
resources :users

you must remove it or put it after

devise_for :users

I found some of the documentation thin - it would have been nice if more comments were added to the code that was generated.

Bug (I will be submitting it):

If you app is not at the root
http://myhost/my_app/
devise will not get the right URLs for sign_in/out paths.


18. elad Apr 12, 2010 at 13:26

@Ryan Bates, Thanks for your detailed answer!


19. Jose Apr 12, 2010 at 14:44

Just a minor suggestion:

# config/application.rb
config.filter_parameters << :password << :password_confirmation


20. Bijan Rahnema Apr 12, 2010 at 15:25

Hi Ryan,

thx for another great screencast. One thing I wanted to mention is that your older screencasts were somehow sharper and had more authentic colors. You changed the screencapture tool?

KR
Bijan


21. klumsyBird Apr 12, 2010 at 21:34

Maybe customize with using twitter/facebook/google/yahoo connect.


22. Doug Apr 12, 2010 at 22:58

Ryan,

I had already decided to use Devise with my new Rails 3 app so your screencast was perfect. Thanks and I'm looking forward to the next one!

Doug


23. Riccardo Tacconi Apr 13, 2010 at 03:55

Is it possible to use devise with LDAP (Active Directory)?

Does devise use an adapter pattern to switch from one auth type to another?


24. Chris Apr 13, 2010 at 05:50

I hate that you have to define all your model attributes with attr_accessible. This could easily lead to cockups where you add a column to your table and forget to add it to the attr_accessible list

I recently wrote an application with the Clearance authentication gem, which uses the same attr_accessible technique as devise. Just before deployment I added a new column to my db and forgot to add it to the attr_accessible list for the user model. I only noticed the problem a month later, and so did my client. This caused a lot of useful data to be lost forever.

It seems silly to have to define the columns, and its a against the ActiveRecord standard


25. José Valim Apr 13, 2010 at 07:14

@Riccardo Devise uses Warden which has the concept of strategies.

Each role (like User and Admin) can have several strategies for authentication and you specify when they are triggered.

Devise ships with both :database_authenticatable (which validates the password given with one stored in the database, both using encryption) and a :token_authenticatable (where users can sign in using a token).

It's easy to add a new strategy. For instance, this guy developed one to authenticate through Imap:

  http://github.com/joshk/devise_imapable

There are other extensions around.

@Chris using attr_accessible is a good practice. Your issue would easily be caught if you had write tests before deploying. Anyway, Devise does not push that, it's up to you to use it or not.

@Soleone Devise still has most of its logic in the model and not in the rack middleware. Take a look at Warden, you will find interesting to know how it works. :)


26. Chris Apr 13, 2010 at 07:38

@Joes

I'm not sure what you mean. Are you saying Devise does not require you to use attr_accessible in order to access your attributes?


27. Ryan Bates Apr 13, 2010 at 09:09

@Bijan, unfortunately the previous video encoding I was using had buggy playback in Snow Leopard so I'm forced to switch. I'm still experimenting with different compression settings.

@Chris, attr_accessible is not part of Devise at all, it's just best practice. If you don't have the attr_accessible line then all database columns would be settable by the user. This is a major security problem especially with the User model, so you should always use attr_accessible there. See Railscasts episode #26 for details.


28. dimas priyanto Apr 13, 2010 at 12:48

i should try this ASAP..


29. Valentine Apr 14, 2010 at 00:34

Thank you for sharing. Nice post!


30. assente Apr 14, 2010 at 02:40

Maybe customize with using twitter/facebook/google/yahoo connect.

+1 is facebooker Rails3 ready?


31. Ramu Apr 14, 2010 at 07:26

awesome Rails! I have fallen love one more time with Rails :)


32. Aaron Graint Apr 15, 2010 at 01:46

Ryan,

Can something like this be used for protecting files as well?

For example, a protected document @ site.com/directory/protected.doc.

Can this intercept the request and verify the user's identity?

My initial thought is No as this might be something for apache, but i would love to hear what you have to say, thanks!


33. Paolo Apr 15, 2010 at 02:52

Great Ryan!
very useful, thanks


34. Stefano Bernardi Apr 15, 2010 at 04:02

Ryan, thanks for another awesome screencast.

I'd like to suggest something for the next episode on devise:
- How to add roles to the user model, and then assign a role in the user signup form, (in order to then use cancan or declarative_auth) - I think this will be clear when you'll try to modify the views.
- How to override some of the gems methods

Thanks and really looking forward to it!


35. Stefano Bernardi Apr 15, 2010 at 06:52

Oh and BTW, another +1 for Twitter/Facebook/Google integration!


36. Larry Finn Apr 15, 2010 at 15:57

Great cast as always. Devise seems to be a great all around solution for our application, so far, but we are now getting into the customization aspect of it so we will see!


37. Helmut Juskewycz Apr 15, 2010 at 23:01

another +1 for OAuth/Twitter/Facebook/Google integration!


38. klusmyBird Apr 17, 2010 at 21:58

I suggest doing a screencast on Captcah. http://ruby-toolbox.com/categories/rails_captcha.html

I see that you have added one just as I'm posting this.


39. Terry Sznober Apr 18, 2010 at 12:08

Does Devise support a way to do "who is online" functionality? How could this be done?


40. Daniel Apr 18, 2010 at 14:23

If your next episode would also cover how to replace an existing install of authlogic, that would be great. I've been looking to replace it for awhile now. Also, one feature I find particularly useful in these tools is the ability to impersonate a user so if that exists, it would be nice to hear of too.


41. Benjamin Orozco Rios Apr 19, 2010 at 14:45

Hi Ryan, great screenscast. I've been wondering how could I replace restful_authentication plugin with Devise plugin in a clean way. Any ideas ?


42. Ryan N Apr 20, 2010 at 18:58

Ryan (or anyone),

I am getting this error when running script/generate devise User

`load_missing_constant': uninitialized constant Devise (NameError)

Also, once I run the devise_install generator I can no longer start my server as I get the same error.

I know I just gotta be missing that one thing ...

Thanks in advanced.


43. John Wong Apr 21, 2010 at 01:54

Great stuff.. just starting to play with devise... Feels very foreign from Authlogic though

Had to checkout the code and look through it all to actually know what methods it overrides

Any good sites that provides info on how to do more indepth customizations?


44. Alex Apr 22, 2010 at 07:06

@Ryan N. What version of Rails are you running? If you are running 3.0, then you have to change from script/generate to rails generate with the rest of the arguments and flags included if you need etc., but if not, then I think you have to have different gem Devise version for Rails 2.3.5... Also, make sure to have dependency. When you first run the app, the app needs to load all of those gems that are, or should be, part of the app... Hope this helps.


45. Creston Apr 22, 2010 at 19:34

So, do the controllers stay locked away in the gem? If I wanted to protect the password during transmission using SSL (e.g., ssl_requirement), how would I do that? Make a copy of the controller in the gem to add the ssl_requirement code? Or is there a better way?


46. John Viviano Apr 25, 2010 at 10:22

Ryan N -

I'm guessing that you are running Rails 2.x. Assuming that you installed the correct Devise gem (1.0.6) and are still getting the error:
`load_missing_constant': uninitialized constant Devise (NameError)

You probably are missing a couple of dependencies in your environment.rb file.

    config.gem 'warden'
    config.gem 'devise'


47. tadatoshi Apr 25, 2010 at 13:01

I tried Devise with Ruby on Rails 3.0 beta 3 and the gotcha mentioned in the screencast turned out to be with config.secret_token.

So with beta 3, you can leave cookie_verification_secret.rb untouched and you have to add config.secret_token to application.rb, e.g. .config.secret_token = 'secret'


48. tadatoshi Apr 25, 2010 at 14:09

P.S. Switching from Beta 2 to Beta 3 actually showed DEPRECATION WARNING when starting up the server or running RSpec specs.

DEPRECATION WARNING: ActionController::Base.cookie_verifier_secret= is deprecated. Please configure it on your application with config.secret_token=.
DEPRECATION WARNING: ActionController::Base.session= is deprecated. Please configure it on your application with config.session_store :cookie_store, :key => '....'.

I guess if you generate Rails app fresh with Beta 3, there is no error any more.


49. Peter Apr 25, 2010 at 16:02

After I run "script/server devise User" and try to view any controller it throws the error message:
"Routing Error

No route matches "/" with {:method=>:get}"

This is a paste of the routes.rb file of the very simple project I was testing devise on ( http://slexy.org/view/s21I0JCOdA )

Has anyone else run across this and managed to rectify it? If so. Please let me know! Any feedback is greatly appreciated.


50. Peter Apr 25, 2010 at 16:24

I managed to get it working by commenting out the 'map.connect' lines at the bottom of the routes.rb file


51. Pavel Apr 28, 2010 at 04:32

Nice cast, I am going to try it out. Very useful.


52. Walter May 05, 2010 at 11:41

One gotcha that bit me was not having actionmailer configured to use sendmail. config.action_mailer.delivery_method = :sendmail in the environment.rb, and everything worked.

Now I'm trying to figure out why it's not reading the configuration changes -- all my e-mails are coming from please-change-me!

Thanks again!


53. Matt Van Horn May 07, 2010 at 08:07

@creston
see here for SSL logins: http://gist.github.com/393520


54. Tomek Wałkuski May 16, 2010 at 04:10

Is is possible to save to two models when signing up? For example I want to save User and Address model during registration.


55. Amol May 19, 2010 at 15:07

For Rails 3.0.0.beta3, in config/application.rb, use this syntax --

config.secret_token = '[secret copied from cookie_verification_secret.rb]'


56. Dave Jun 13, 2010 at 15:02

Ryan,

How did you get bundler to work with rake? I'm running bundle 0.9.26 and rake 0.8.7, but rake is erroring out when I do the first db:migrate. I've read on some other posts that you need to 'gem install' separately not using 'bundle', but you're doing it. What is your trick?


57. jason Jun 17, 2010 at 02:53

FYI to use device in Rails3 you now need to update your gem to gem "devise", :git => "git://github.com/plataformatec/devise.git"


58. shevtiawan Jun 20, 2010 at 21:24

I already have the user model.
How should I use Devise to integrate it with legacy system?

Thanks in advance.


59. onemanarmy Jun 28, 2010 at 23:01

Like Jason mentioned, you can also use Devise 1.1.rc2. This helped me solve an 'uninitialized constant UsersController' error at /sign_up.


60. Paul Jul 01, 2010 at 06:39

I have the same problem as @Walter with the password email not working with smtp. Unfortunately, I can't set my environment to use sendmail. Has anyone gotten this to work with smtp? I get "A sender (Return-Path, Sender or From) required to send a message". Other than that, it's working great in Rails 3!


61. Cheap Microsoft Windows & Office Ultimate Product Key Jul 23, 2010 at 00:03

<h1><a href="http://www.win7key.net/windows-7-key-c-51.html" title="Windows 7 Key, Windows 7 Update, Windows 7 Product Key, Windows 7 Ultimate Key.">windows 7 key</a></h1>


64. Andy Jul 28, 2010 at 07:56

Great Railscast!

Question: Are you using TextMate for your editing? What bundles do you have installed for the "ife" shortcut and the other HTML shortcuts?

I have the Ruby On Rails bundle installed, but all the shortcuts don't seem to work.


64. Jordan Aug 01, 2010 at 23:40

Our goods are popular all over the world with High Quality, Competitive Price, Best Service and Safe Delivery.Do not hesitate to have our merchandise is your best choice! Soon as likely to purchase the bar!


64. Johan Svensson Aug 03, 2010 at 03:52

I have rails Rails 2.3.8 and Devise 1.0.8. I have followed the installation instruction, but when trying to access /users/sign_in for the first time after modified routes.rb, I get

Internal Server Error
undefined method `[]' for :users:Symbol

When I reload, I get

Routing Error
No route matches "/users/sign_up" with {:method=>:get}

If putting map.devise_for :users above other map.s, I get the same kind of routing errors when trying to access for example /artists or /songs.

Am I missing something?


65. Johan Svensson Aug 03, 2010 at 04:31

Continue from previous comment: Oh, and by the way. In my eyes, the output of rake routes looks good:

http://pastebin.com/LEA2LXpV


66. UGG Boots on sale Aug 10, 2010 at 18:43

Gooooooooooooooooooood luck ~~!!


67. free directory list Aug 11, 2010 at 22:42

you for sharing.Nice post


68. oppo Aug 15, 2010 at 08:39

This was really useful. Thanks Ryan!


69. Rip Blu-ray for Mac Aug 18, 2010 at 01:37

Thanks,it's so good.
suport!


70. AVI to iPad Aug 19, 2010 at 00:54

This was really useful.


71. Air Jordan Force 4 Aug 19, 2010 at 20:55

Great post! Thanks for share. I will instantly grab your rss feed to stay informed of any updates.


72. Wholesale hats Aug 20, 2010 at 20:06

I really liked your article and I shared with my friends in my facebook account ..
I gave my site a few examples below. If you appreciate my comments in you enter.


73. converse all star Aug 20, 2010 at 20:51

love converse all star,love yourself.High quality low price.It's fit for you.


74. lily Aug 23, 2010 at 23:34

What youre saying is completely true. I know that everybody must say the same thing, but I just think that you put it
in a way that everyone can understand. I also love the images you put in here. They fit so well with what youre trying to say.
Im sure youll reach so many people with what youve got to say.<b><a href=http://www.tygluegun.com>glue stick</a></b> |<b><a href=http://www.tygluegun.com>glue gun</a></b>
|<b><a href=http://www.wanjia-ylm.cn>booster cable</a></b> |<b><a href=http://www.wanjia-ylm.cn>power cord</a></b>


75. lina Aug 23, 2010 at 23:50

Well done, I admire the valuable information you offer in your articles. I will bookmark your blog
and have my children check up here often. I am quite sure they will learn lots of new stuff here than
 anybody else<b><a href=http://www.hzhtdq.cn>power strip</a></b> |<b><a href=http://www.hzhtdq.cn>extension cord</a></b>
 |<b><a href=http://www.hzhtdq.cn>trouble light</a></b>


76. Andrew Aug 25, 2010 at 17:22

To make this clear for everyone: If you are using Rails 3, and you're getting this message: No route matches "/" or something similar, you must use the latest version of Devise on github. Modify your Gemfile to say :

gem "devise", :git => "git://github.com/plataformatec/devise.git"


77. Andrew Aug 25, 2010 at 17:28

Also, I would love to see a tutorial on integrating Facebook connect with Devise (since that's my next step!)

I love your tutorials by the way. Your tutorials are one of the reasons why I am switching to Rails. They make it easy for me to learn quickly. Thanks for what you do for the community!


78. louis vuitton shoes Aug 26, 2010 at 21:17

Thanks for sharing your article. I really enjoyed it. I put a link to my site to here so other people can read it. My readers have about the same interets


79. Evan Aug 28, 2010 at 06:40

Ryan, I know this episode was released a few months ago but you might want to consider releasing an update for it since the current versions of Devise is 1.1.2 and has a few changes. Thanks for the screencasts.


80. mbt shoes sale Aug 28, 2010 at 09:47

How should I use Devise to integrate it with legacy system?

Thanks in advance.


81. cheap mbt shoes Aug 28, 2010 at 10:09

I love your tutorials by the way. Your tutorials are one of the reasons why I am switching to Rails. They make it easy for me to learn quickly. Thanks for what you do for the community!


82. cheap ugg boots sale Aug 28, 2010 at 10:20

FYI to use device in Rails3 you now need to update your gem to gem "devise", :git => "git://github.com/plataformatec/devise.git"


83. rap Aug 29, 2010 at 08:53

me too :)


84. eztoo Aug 29, 2010 at 18:29

Try our products. There will be surprises.
http://www.eztoosoft.com


85. herve leger dress Aug 30, 2010 at 19:47

Yuyao Huaneng sanitary ware factory is specialized in production of plumbing fittings.


86. snow boots Aug 30, 2010 at 20:23

Also good to note is that it supports other ORM's as well, not just ActiveRecord, and you can build your own custom modules if needed.


87. levis belts Sep 01, 2010 at 20:57

Intimately, the post is actually the best on this laudable topic. I harmonize with your conclusions and will eagerly look forward to your future updates. Saying thanks will not just be adequate, for the fantastic lucidity in your writing.


88. blu ray ripper Sep 01, 2010 at 23:40

It looks nice and I am in need of this.

Add your comment:

(SKIP THIS ONE)

(required)

(not shown)


(use pastie or gist for code)

sponsored by:
if you want to help:
required:
Get Quicktime Player
Give Back to Open Source