Track Devise login activity
🍊 Battle-tested at Instacart
Add this line to your application’s Gemfile:
gem 'authtrail'
And run:
rails generate authtrail:install
rails db:migrate
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 scopestrategy
- Devise strategyidentity
- email addresssuccess
- whether the login succeededfailure_reason
- if the login faileduser
- the user if the login succeededcontext
- controller and actionip
- IP addressuser_agent
andreferrer
- from browsercity
,region
, andcountry
- from IPcreated_at
- time of event
Exclude certain attempts from tracking - useful if you run acceptance tests:
AuthTrail.exclude_method = proc do |info|
info[:identity] == "[email protected]"
end
Write data somewhere other than the login_activities
table:
AuthTrail.track_method = proc do |info|
# code
end
Associate LoginActivity
with your user model:
class Manager < ApplicationRecord
has_many :login_activities, as: :user
end
The LoginActivity
model uses a polymorphic association out of the box, so login activities can belong to different models (User, Admin, Manager, etc).
IP geocoding is performed in a background job so it doesn’t slow down web requests. You can disable it entirely with:
AuthTrail.geocode = false
Set job queue for geocoding
AuthTrail::GeocodeJob.queue_as :low
To avoid calls to a remote API, download the GeoLite2 City database and configure Geocoder to use it.
Add this line to your application’s Gemfile:
gem 'maxminddb'
And create an initializer at config/initializers/geocoder.rb
with:
Geocoder.configure(
ip_lookup: :geoip2,
geoip2: {
file: Rails.root.join("lib", "GeoLite2-City.mmdb")
}
)
Protect the privacy of your users by encrypting fields that contain personal information, such as identity
and ip
. attr_encrypted is a great library for this.
class LoginActivity < ApplicationRecord
attr_encrypted :identity, ...
attr_encrypted :ip, ...
end
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.
Works with Rails 5+
View the changelog
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