Upgrade to Pro — share decks privately, control downloads, hide ads and more …

What Devise is doing when you are not looking

Lucas Mazza
September 04, 2014

What Devise is doing when you are not looking

Devise is the go-to authentication gem for Rails apps and you probably worked with it once or twice, but do you know how Devise works inside your app? We are going to talk about how Devise is designed to provide a full stack authentication solution, who are the main building blocks of the library and how we can extend their behaviour to our will in our applications.

Lucas Mazza

September 04, 2014
Tweet

More Decks by Lucas Mazza

Other Decks in Technology

Transcript

  1. database_authenticatable => Devise::Models::DatabaseAuthenticatable confirmable => Devise::Models::Confirmable lockable => Devise::Models::Lockable omniauthable

    => Devise::Models::Omniauthable recoverable => Devise::Models::Recoverable registerable => Devise::Models::Registerable rememberable => Devise::Models::Rememberable timeoutable => Devise::Models::Timeoutable trackable => Devise::Models::Trackable validatable => Devise::Models::Validatable Everything is opt in
  2. $ bin/rake routes Prefix Verb URI Pattern Controller#Action new_user_session GET

    /users/sign_in(.:format) devise/sessions#new user_session POST /users/sign_in(.:format) devise/sessions#create destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy user_password POST /users/password(.:format) devise/passwords#create new_user_password GET /users/password/new(.:format) devise/passwords#new edit_user_password GET /users/password/edit(.:format) devise/passwords#edit PATCH /users/password(.:format) devise/passwords#update PUT /users/password(.:format) devise/passwords#update cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel user_registration POST /users(.:format) devise/registrations#create new_user_registration GET /users/sign_up(.:format) devise/registrations#new edit_user_registration GET /users/edit(.:format) devise/registrations#edit PATCH /users(.:format) devise/registrations#update PUT /users(.:format) devise/registrations#update DELETE /users(.:format) devise/registrations#destroy
  3. Thing::Application.routes.draw do authenticate :user, -> { |user| user.admin? } do

    mount Resque::Server.new, at: 'resque' end ! devise_scope :user do get 'sign_in', to: 'devise/sessions#new' end end
  4. app/views/devise/ "## confirmations $ &## new.html.erb "## mailer $ "##

    confirmation_instructions.html.erb $ "## reset_password_instructions.html.erb $ &## unlock_instructions.html.erb "## passwords $ "## edit.html.erb $ &## new.html.erb "## registrations $ "## edit.html.erb $ &## new.html.erb "## sessions $ &## new.html.erb "## shared $ &## _links.html.erb &## unlocks &## new.html.erb rails g devise:views [-v registrations confirmations]
  5. Friendly Reminder ! If you found a security bug, please

    do not open an Issue on GitHub. Report to [email protected] instead.
  6. class User < ActiveRecord::Base # Deliver notifications using Rails 4.2

    ‘deliver_later'. def send_devise_notification(email, *args) devise_mailer.send(email, self, *args).deliver_later end end
  7. class User < ActiveRecord::Base # Delivers a welcome notification when

    the user confirms # its email. def after_confirmation send_devise_notification(:welcome) end end
  8. Devise.timeout_in = 30.minutes ! class User < ActiveRecord::Base devise :database_authenticatable,

    :timeoutable def timeout_in staff? ? 10.minutes : 2.hours end end Instance based configuration
  9. class User < ActiveRecord::Base devise :database_authenticatable, :timeoutable, timeout_in: 2.hours end

    ! class Admin < ActiveRecord::Base devise :database_authenticatable, :timeoutable, timeout_in: 10.minutes end Scope based configuration
  10. class RegistrationsController < Devise::RegistrationsController # Track down registration origins through

    a param def build_resource(hash = nil) super self.resource.origin = params['_origin'] self.resource end end
  11. class ApplicationController < ActionController::Base # Include the subdomain in the

    i18n interpolation options. def devise_i18n_options(options) options.merge(subdomain: current_account.subdomain) end end
  12. en: devise: confirmations: confirmed: "Your email address has been successfully

    confirmed." send_instructions: "You will receive an email with instructions for how to confirm your email address in a few minutes." send_paranoid_instructions: "If your email address exists in our database, you will receive an email with instructions for how to confirm your email address in a few minutes." failure: already_authenticated: "You are already signed in." inactive: "Your account is not activated yet." invalid: "Invalid email or password." locked: "Your account is locked." last_attempt: "You have one more attempt before your account is locked." not_found_in_database: "Invalid email address or password." # ...
  13. config.warden do |manager| manager.failure_app = MyFailureApp end ! class MyFailureApp

    < Devise::FailureApp def redirect_url warden_options[:checkout] ? checkout_sign_in_path : super end end Custom Failure
  14. class RemoteAuthenticable < Devise::Strategies::Authenticatable # ... end ! Warden::Strategies.add :remote_authenticable,

    RemoteAuthenticable Devise.add_module :remote_authenticable, strategy: true ! class User < ActiveRecord::Base devise :remote_authenticable end Alternative Strategies