This is a proof-of-concept application designed to test a 2FA (two factor authentication) system in Rails using the bare minimum, in a "roll your own" style.
It uses three specific gems, one to create and verify OTP tokens, another to convert the token to base32, and the last one to join it all together, generating a QR Code so the user can read the token in his mobile phone.
- Download or clone this repository
- Install Ruby and run
bundler - Create database with
rails db:setup - If needed, run
rails db:seed - Run the
rails serverand log in asadminusing the passwordadmin - Go to
/users/1(the show view) and activate 2FA - Read the QR Code using Google Authenticator or other similar app
- Copy the given nonce tokens in case you lose access to your phone.
There is a User model, which only has basic name/password columns, along with
the mfa_secret column that stores the 2FA token, if present. If this column
is null, it means the user is not using 2FA, so it won't prompt for this on
login.
Once the user decides to activate the 2FA functionality, a random 32-byte hex
string is generated and stored in the mfa_secret column. 10 nonce tokens are
also created at this time, erasing all tokens that might previously exist for
that user. Each nonce token is also a 32-byte random hex string.
The base32 gem is used to convert this mfa_secret to base32, which is
generally required for the TOTP protocol. The rotp gem is used to generate
the TOTP URI, which is then used by the rqrcode gem to create an SVG image of
the QR Code representing this URI.
When the user logs in, he will need to provide his name and password, and if those are correct, it will prompt for his 2FA token, which is a time based token. If the user loses access to this token, he can use one of the 10 nonce tokens. Once one of these tokens is used, it cannot be reused, so if the user loses his 2FA access and uses up all of his nonces, he cannot access his account anymore. Obviously a "production-ready" app will have ways to prevent this.
The rotp gem is not only used to generate the TOTP URI, but is also used to
verify the token when the user is logging in. Although this app does not make
use of this feature, rotp also allows for time drift (when the system clock
of the server is different from the system clock of the mobile phone).
If the user doesn't want to use 2FA anymore, he can disable it from his user's
show page. The mfa_secret token will be erased, along with all of his nonce
tokens.