Two (2) Factor Authentication (2FA) Crystal code which uses the Time-based One-time Password (TOTP) algorithm. You can use this code with the Google Authenticator mobile app or the Authy mobile or browser app.
- See the wikipedia page about TOTP
Add this to your application's shard.yml
:
dependencies:
crystal-two-factor-auth:
github: SushiChain/crystal-two-factor-auth
require "crystal-two-factor-auth"
# TOTP.generate_base32_secret
base32_secret = "NY4A5CPJZ46LXZCP"
# this is the name of the key which can be displayed by the authenticator program
key_id = "kings@sushichain.io"
# generate the QR code
# we can display this image to the user to let them load it into their auth program
puts "Image url: #{TOTP.qr_code_url(key_id, base32_secret)}"
# we can use the auth number here and compare it against user input
# auth_number = TOTP.generate_number_string(base32_secret)
# is_valid = TOTP.validate_number_string(base32_secret, auth_number)
# this loop shows how the number changes over time
while true
diff = TOTP::DEFAULT_TIME_STEP_SECONDS - ((Time.now.epoch_ms / 1000) % TOTP::DEFAULT_TIME_STEP_SECONDS)
code = TOTP.generate_number_string(base32_secret)
puts "Secret code = #{code}, change in #{diff} seconds"
sleep 1
end
See the example in spec/two_factor_auth_example.cr
- Use
generate_base32_secret()
to generate a secret key in base32 format for the user. For example:"NY4A5CPJZ46LXZCP"
- Store the secret key in the database associated with the user account
- Display the QR image URK returned by
qr_code_url(...)
to the user. Here's a sample which uses GoogleAPI's: - User uses the image to load the secret key into their authenticator application (google auth / authy)
- The user enters the number from the authenticator application into the login form
- Read the secret associated with the user account from the database
- The server compares the user input with the output from
generate_current_number_string(...)
- If they are equal then the user is allowed to log in
- Fork it ( https://github.com/SushiChain/crystal-two-factor-auth/fork )
- Create your feature branch (git checkout -b my-new-feature)
- Commit your changes (git commit -am 'Add some feature')
- Push to the branch (git push origin my-new-feature)
- Create a new Pull Request
- kingsleyh Kingsley Hendrickse - creator, maintainer