ankane / Authtrail
Programming Languages
AuthTrail
Track Devise login activity
🍊 Battle-tested at Instacart
Installation
Add this line to your application’s Gemfile:
gem 'authtrail'
To encrypt email and IP addresses, install Lockbox and Blind Index and run:
rails generate authtrail:install --lockbox
rails db:migrate
If you prefer not to encrypt data, run:
rails generate authtrail:install
rails db:migrate
How It Works
A LoginActivity
record is created every time a user tries to login. You can then use this information to detect suspicious behavior. Data includes:
-
scope
- Devise scope -
strategy
- Devise strategy -
identity
- email address -
success
- whether the login succeeded -
failure_reason
- if the login failed -
user
- the user if the login succeeded -
context
- controller and action -
ip
- IP address -
user_agent
andreferrer
- from browser -
city
,region
,country
,latitude
, andlongitude
- from IP -
created_at
- time of event
Features
Exclude certain attempts from tracking - useful if you run acceptance tests
AuthTrail.exclude_method = lambda do |data|
data[:identity] == "[email protected]"
end
Add or modify data - also add new fields to the login_activities
table if needed
AuthTrail.transform_method = lambda do |data, request|
data[:request_id] = request.request_id
end
Store the user on failed attempts
AuthTrail.transform_method = lambda do |data, request|
data[:user] ||= User.find_by(email: data[:identity])
end
Write data somewhere other than the login_activities
table
AuthTrail.track_method = lambda do |data|
# code
end
Use a custom identity method
AuthTrail.identity_method = lambda do |request, opts, user|
if user
user.email
else
request.params.dig(opts[:scope], :email)
end
end
Associate login activity with your user model
class User < ApplicationRecord
has_many :login_activities, as: :user # use :user no matter what your model name
end
The LoginActivity
model uses a polymorphic association so it can be associated with different user models.
Geocoding
AuthTrail uses Geocoder for geocoding. We recommend configuring local geocoding or load balancer geocoding so IP addresses are not sent to a 3rd party service. If you do use a 3rd party service and adhere to GDPR, be sure to add it to your subprocessor list.
To enable geocoding, update config/initializers/authtrail.rb
:
AuthTrail.geocode = true
Geocoding is performed in a background job so it doesn’t slow down web requests. Set the job queue with:
AuthTrail.job_queue = :low_priority
Local Geocoding
For privacy and performance, we recommend geocoding locally. Add this line to your application’s Gemfile:
gem 'maxminddb'
For city-level geocoding, download the GeoLite2 City database and create config/initializers/geocoder.rb
with:
Geocoder.configure(
ip_lookup: :geoip2,
geoip2: {
file: "path/to/GeoLite2-City.mmdb"
}
)
For country-level geocoding, install the geoip-database
package. It’s preinstalled on Heroku. For Ubuntu, use:
sudo apt-get install geoip-database
And create config/initializers/geocoder.rb
with:
Geocoder.configure(
ip_lookup: :maxmind_local,
maxmind_local: {
file: "/usr/share/GeoIP/GeoIP.dat",
package: :country
}
)
Load Balancer Geocoding
Some load balancers can add geocoding information to request headers.
AuthTrail.geocode = false
AuthTrail.transform_method = lambda do |data, request|
data[:country] = request.headers["<country-header>"]
data[:region] = request.headers["<region-header>"]
data[:city] = request.headers["<city-header>"]
end
Check out this example
Other Notes
We recommend using this in addition to Devise’s Lockable
module and Rack::Attack.
Check out Hardening Devise and Secure Rails for more best practices.
Upgrading
0.2.0
To store latitude and longitude, create a migration with:
add_column :login_activities, :latitude, :float
add_column :login_activities, :longitude, :float
History
View the changelog
Contributing
Everyone is encouraged to help improve this project. Here are a few ways you can help:
- Report bugs
- Fix bugs and submit pull requests
- Write, clarify, or fix documentation
- Suggest or add new features
To get started with development and testing:
git clone https://github.com/ankane/authtrail.git
cd authtrail
bundle install
bundle exec rake test