class Authlogic::Session::Base

This is the most important class in Authlogic. You will inherit this class for your own eg. ‘UserSession`.

Ongoing consolidation of modules

We are consolidating modules into this class (inlining mixins). When we are done, there will only be this one file. It will be quite large, but it will be easier to trace execution.

Once consolidation is complete, we hope to identify and extract collaborating objects. For example, there may be a “session adapter” that connects this class with the existing ‘ControllerAdapters`. Perhaps a data object or a state machine will reveal itself.

Activation

Activating Authlogic requires that you pass it an Authlogic::ControllerAdapters::AbstractAdapter object, or a class that extends it. This is sort of like a database connection for an ORM library, Authlogic can’t do anything until it is “connected” to a controller. If you are using a supported framework, Authlogic takes care of this for you.

ActiveRecord Trickery

Authlogic looks like ActiveRecord, sounds like ActiveRecord, but its not ActiveRecord. That’s the goal here. This is useful for the various rails helper methods such as form_for, error_messages_for, or any method that expects an ActiveRecord object. The point is to disguise the object as an ActiveRecord object so we can take advantage of the many ActiveRecord tools.

Brute Force Protection

A brute force attacks is executed by hammering a login with as many password combinations as possible, until one works. A brute force attacked is generally combated with a slow hashing algorithm such as BCrypt. You can increase the cost, which makes the hash generation slower, and ultimately increases the time it takes to execute a brute force attack. Just to put this into perspective, if a hacker was to gain access to your server and execute a brute force attack locally, meaning there is no network lag, it would probably take decades to complete. Now throw in network lag and it would take MUCH longer.

But for those that are extra paranoid and can’t get enough protection, why not stop them as soon as you realize something isn’t right? That’s what this module is all about. By default the consecutive_failed_logins_limit configuration option is set to 50, if someone consecutively fails to login after 50 attempts their account will be suspended. This is a very liberal number and at this point it should be obvious that something is not right. If you wish to lower this number just set the configuration to a lower number:

class UserSession < Authlogic::Session::Base
  consecutive_failed_logins_limit 10
end

Callbacks

Between these callbacks and the configuration, this is the contract between me and you to safely modify Authlogic’s behavior. I will do everything I can to make sure these do not change.

Check out the sub modules of Authlogic::Session. They are very concise, clear, and to the point. More importantly they use the same API that you would use to extend Authlogic. That being said, they are great examples of how to extend Authlogic and add / modify behavior to Authlogic. These modules could easily be pulled out into their own plugin and become an “add on” without any change.

Now to the point of this module. Just like in ActiveRecord you have before_save, before_validation, etc. You have similar callbacks with Authlogic, see the METHODS constant below. The order of execution is as follows:

before_persisting
persist
after_persisting
[save record if record.has_changes_to_save?]

before_validation
before_validation_on_create
before_validation_on_update
validate
after_validation_on_update
after_validation_on_create
after_validation
[save record if record.has_changes_to_save?]

before_save
before_create
before_update
after_update
after_create
after_save
[save record if record.has_changes_to_save?]

before_destroy
[save record if record.has_changes_to_save?]
after_destroy

Notice the “save record if has_changes_to_save” lines above. This helps with performance. If you need to make changes to the associated record, there is no need to save the record, Authlogic will do it for you. This allows multiple modules to modify the record and execute as few queries as possible.

WARNING: unlike ActiveRecord, these callbacks must be set up on the class level:

class UserSession < Authlogic::Session::Base
  before_validation :my_method
  validate :another_method
  # ..etc
end

You can NOT define a “before_validation” method, this is bad practice and does not allow Authlogic to extend properly with multiple extensions. Please ONLY use the method above.

HTTP Basic Authentication

Handles all authentication that deals with basic HTTP auth. Which is authentication built into the HTTP protocol:

http://username:password@whatever.com

Also, if you are not comfortable letting users pass their raw username and password you can use a single access token, as described below.

Magic Columns

Just like ActiveRecord has “magic” columns, such as: created_at and updated_at. Authlogic has its own “magic” columns too:

Multiple Simultaneous Sessions

See ‘id`. Allows you to separate sessions with an id, ultimately letting you create multiple sessions for the same user.

Timeout

Think about financial websites, if you are inactive for a certain period of time you will be asked to log back in on your next request. You can do this with Authlogic easily, there are 2 parts to this:

  1. Define the timeout threshold:

acts_as_authentic do |c|
  c.logged_in_timeout = 10.minutes # default is 10.minutes
end
  1. Enable logging out on timeouts

class UserSession < Authlogic::Session::Base
  logout_on_timeout true # default is false
end

This will require a user to log back in if they are inactive for more than 10 minutes. In order for this feature to be used you must have a last_request_at datetime column in your table for whatever model you are authenticating with.

Params

This module is responsible for authenticating the user via params, which ultimately allows the user to log in using a URL like the following:

https://www.domain.com?user_credentials=4LiXF7FiGUppIPubBPey

Notice the token in the URL, this is a single access token. A single access token is used for single access only, it is not persisted. Meaning the user provides it, Authlogic grants them access, and that’s it. If they want access again they need to provide the token again. Authlogic will NEVER try to persist the session after authenticating through this method.

For added security, this token is ONLY allowed for RSS and ATOM requests. You can change this with the configuration. You can also define if it is allowed dynamically by defining a single_access_allowed? method in your controller. For example:

class UsersController < ApplicationController
  private
    def single_access_allowed?
      action_name == "index"
    end

Also, by default, this token is permanent. Meaning if the user changes their password, this token will remain the same. It will only change when it is explicitly reset.

You can modify all of this behavior with the Config sub module.

Perishable Token

Maintains the perishable token, which is helpful for confirming records or authorizing records to reset their password. All that this module does is reset it after a session have been saved, just keep it changing. The more it changes, the tighter the security.

See Authlogic::ActsAsAuthentic::PerishableToken for more information.

Scopes

Authentication can be scoped, and it’s easy, you just need to define how you want to scope everything. See ‘.with_scope`.

Unauthorized Record

Allows you to create session with an object. Ex:

UserSession.create(my_user_object)

Be careful with this, because Authlogic is assuming that you have already confirmed that the user is who he says he is.

For example, this is the method used to persist the session internally. Authlogic finds the user with the persistence token. At this point we know the user is who he says he is, so Authlogic just creates a session with the record. This is particularly useful for 3rd party authentication methods, such as OpenID. Let that method verify the identity, once it’s verified, pass the object and create a session.

Magic States

Authlogic tries to check the state of the record before creating the session. If your record responds to the following methods and any of them return false, validation will fail:

Method name           Description
active?               Is the record marked as active?
approved?             Has the record been approved?
confirmed?            Has the record been confirmed?

Authlogic does nothing to define these methods for you, its up to you to define what they mean. If your object responds to these methods Authlogic will use them, otherwise they are ignored.

What’s neat about this is that these are checked upon any type of login. When logging in explicitly, by cookie, session, or basic http auth. So if you mark a user inactive in the middle of their session they wont be logged back in next time they refresh the page. Giving you complete control.

Need Authlogic to check your own “state”? No problem, check out the hooks section below. Add in a before_validation to do your own checking. The sky is the limit.

Validation

The errors in Authlogic work just like ActiveRecord. In fact, it uses the ‘ActiveModel::Errors` class. Use it the same way:

“‘ class UserSession

validate :check_if_awesome

private

def check_if_awesome
  if login && !login.include?("awesome")
    errors.add(:login, "must contain awesome")
  end
  unless attempted_record.awesome?
    errors.add(:base, "You must be awesome to log in")
  end
end

end “‘