Skip to content
Example Rails TFA application using Authlogic and Google Authenticator
Ruby JavaScript CoffeeScript
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.
spec simplify specs for validate_code Jul 26, 2013
Guardfile add Spork and Guard to speed up spec feedback Jun 22, 2012
Rakefile add examples/rails_app Feb 18, 2012


Two Factor Authentication Example

A bare bones example Rails 3.2 application and test suite demonstrating the use of the Authlogic gem and custom two-factor authentication (TFA) with Google authenticator support.

Typical Use Case

Intranet application with username/password authentication for LAN users. Remote users are required to use TFA.

Demo Features

  • Authlogic handles authentication, there are no changes to Authlogic, TFA is completely separate and invoked after Authlogic authorization.
  • Google Authenticator QR code secret entry without generating images (RQRCode) or sending secrets to the charting services.
  • TFA confirmation will expire with the session but can expire before the session if required.
  • TFA confirmation code brute force protection applies to the user, not just the session. Lockout after 5 failures, requires manual reset.

Demo Limitations

Correctable in a production application

  • Production implementations must use SSL otherwise this implementation, and Authlogic itself, is vulnerable to session hijacking. See below for configuration options.
  • TFA secret and TFA failure count reset is not implemented
  • Users can view other user secrets, they should be scoped to the current user, i.e. a 'My Account' page.
  • TFA Google Authenticator secret setup requires viewing the user record, the demo has all IP addresses including the localhost address restricted by default. This can be changed. See configuration options below.

Example Application Usage

git clone
cd two_factor_authentication_example

bundle install

bundle exec rake db:migrate
bundle exec rake db:seed

bundle exec rails server

login creditials for the admin user

login: admin
password: admin
Google Authenticator time based two_factor_secret (spaces are optional): v6na sf4k fe45 qxbq

run the app

firefox http://localhost:3000

run the RSpec test suite

bundle exec rake db:test:prepare

bundle exec rspec

for development, start-up the Spork process via Guard

bundle exec guard

Demo Configuration Options

TFA configuration

Change TFA brute force failure count in app/models/user.rb

def two_factor_failure_count_exceeded?
  self.two_factor_failure_count >= 5

Change length of time the TFA confirmation is valid in app/models/user.rb

def two_factor_confirmed_at_valid_for

Change the sliding window width from the default of one 30 second window in app/controllers/user_sessions_controller.rb

# Use a sliding time window to validate tokens.  System clock inaccuracy can
# be tolerated at the expense a small decrease in security.   A value of 0
# will disable the sliding window
# A value of 2 will check tokens in two windows before and after the current
# 30 second window. ie. +/- 60 seconds surrounding the current window.
# @return [Integer] width of the window in 30 second increments
def sliding_window_width

Excluding IP Ranges from TFA

Change ApplicationController to allow all logins to bypass TFA

  def two_factor_excluded_ip_addresses

Change ApplicationController to allow a localhost subnet to access without TFA

  def two_factor_excluded_ip_addresses

Change ApplicationController to allow LAN subnet to access without TFA

  def two_factor_excluded_ip_addresses

Change ApplicationController to allow both localhost and LAN subnet to access without TFA

  def two_factor_excluded_ip_addresses
    [IPAddress.parse(""), IPAddress.parse("")]

Forcing SSL in Production


# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
config.force_ssl = true


# Should the cookie be set as httponly?  If true, the cookie will not be
# accessable from javascript
httponly true

# Should the cookie be set as secure?  If true, the cookie will only be sent
# over SSL connections
# Secure the cookie when the session_store is secure (production SSL)
secure true


add these options to the session_store

:httponly => true,
:secure => Rails.env.production?




Additional References

Example Application Generation

Initial generation

rails version

rails -v

    Rails 3.2.1

generate basic rails application

rails new two_factor_authentication_example --skip-bundle -T


gem "authlogic", "~> 3.1.0"
gem "rotp", "~> 1.3.2"
gem "rqrcode", "~> 0.4.2"
gem "ipaddress", "~> 0.8.0"
gem 'uuidtools', "~> 2.1.2"

group :test, :development do
  gem "ruby-debug"
  gem "rspec-rails", "~> 2.8"
  gem "factory_girl_rails", "~> 1.6"
  gem "capybara", "~> 1.1"
  gem "database_cleaner", "~> 0.7.1"
  gem "timecop", "= 0.3.5"


bundle update

basic user scaffold and manual authlogic configuration

rails generate scaffold user email:string first_name:string last_name:string login:string --fixture-replacement

add admin user seed

 rake db:seed

Future Rails updates

rails new .


Copyright (c) 2012-2013 GearheadForHire, LLC. See LICENSE for details.

Something went wrong with that request. Please try again.