Skip to content
Daniel Martin edited this page Feb 4, 2019 · 3 revisions

Warden unfortunately requires some setup. This can be alleviated somewhat for your framework by using plugins if they're available.

Rack Setup

Warden must be downstream of some kind of session middleware. It must have a failure application declared, and you should declare which strategies to use by default.

Rack::Builder.new do
  use Rack::Session::Cookie, :secret => "replace this with some secret key"

  use Warden::Manager do |manager|
    manager.default_strategies :password, :basic
    manager.failure_app = BadAuthenticationEndsUpHere
  end

  run SomeApp
end

Session Setup

One of the results of using any kind of object as a user object, is that you need to tell Warden how to serialize the user in and out of the session. You'll need to set this up

Warden::Manager.serialize_into_session do |user|
  user.id
end

Warden::Manager.serialize_from_session do |id|
  User.get(id)
end

This can of course be as complex as needed.

Declare Some Strategies

You'll need to declare some strategies to be able to get Warden to actually authenticate. See the Strategies page for more information.

Use it in your application

env['warden'].authenticate!  # use defaults :password and :basic
env['warden'].authenticate! :password # Use the :password strategy only

Advanced Setup (with scopes)

If you just need a single kind of user and don't need to make use of scopes, then perhaps you should skip this part (or at least don't worry about it too much).

When setting up warden, different scopes can be setup to behave differently. This can be a very powerful technique. An example will explain this better than words so lets have a look.

# setup extracted from a working rails application
use Warden::Manager do |config|
  config.failure_app = ->(env) do
    env['REQUEST_METHOD'] = 'GET'
    SessionsController.action(:new).call(env)
  end
  config.default_scope = :user

  config.scope_defaults :user,        :strategies => [:password]
  config.scope_defaults :account,     :store => false,  :strategies => [:account_by_subdomain]
  config.scope_defaults :membership,  :store => false,  :strategies => [:membership, :account_owner]

  config.scope_defaults(
    :api,
    :strategies => [:api_token],
    :store      => false,
    :action     => "unauthenticated_api"
  )
end

There's a lot going on here.

Default Scope

By default, warden will set a default scope for you and use that, but you can overwrite it. We've overwritten it here to be :user. This means that env['warden'].authenticate! will authenticate within the :user scope (since none was specified).

Scope Defaults

Each scope can be set with a list of default behaviour. The strategy list to use, whether to persist the result in the session or not, and even the action of the failure application can be set on a per scope basis.

To use any of these scopes in the predefined way, you just authenticate for that scope:

env['warden'].authenticate! :scope => :api

This call will authenticate via the :api_token strategy, will not persist in the session and will make the "user" available in the :api scope. i.e. env['warden'].user(:api).