You can specify a custom drift value. Drift is the number of seconds that the client
and server are allowed to drift apart. Default value is 5 seconds.
classUseract_as_google_authenticated:drift=>31end
Lookup Token
You can also specify which column the appropriate MfaSession subclass should use to look up the record:
The above will cause the UserMfaSession class to call User.where(:salt => cookie_salt) or User.scoped(:conditions => { :salt => cookie_salt }) to find the appropriate record.
A note about record lookup
GoogleAuthenticatorRails makes one very large assumption when attempting to lookup a record. If your MfaSession subclass is named UserMfaSession it assumes you're trying to lookup a User record. Currently, there is no way to configure this, so if you're trying to lookup a VeryLongModelNameForUser you'll need to name your MfaSession subclass VeryLongModelNameForUserMfaSession.
A note about cookie creation and Session::Persistence::TokenNotFound
GoogleAuthenticatorRails looks up the record based on the cookie created when you call MfaSession#create. The #create method looks into the record class (in our example, User) and looks at the configured :lookup_token option. It uses that option to save two pieces of information into the cookie, the id of the record and the token, which defaults to persistence_token. persistence_token is what Authlogic uses, which this gem was originally designed to work with.
This can cause a lot of headaches if the model isn't configured correctly, and will cause a GoogleAuthenticatorRails::Session::Persistence::TokenNotFound error.
The above example will fail because the User class doesn't have a persistence_token method. The fix for this is to configure actions_as_google_authentic to use the right column:
# app/models/user.rbclassUser < ActiveRecord::Baseacts_as_google_authentic:lookup_token=>:saltend# Model has attributes:# id: integer# name: string# salt: string# app/models/user_mfa_session.rbclassUserMfaSession < GoogleAuthenticatorRails::Session::Baseend# app/controllers/mfa_session_controller.rbclassMfaSessionController < ApplicationControllerdefcreateUserMfaSession.create(user)endend
This call to #create will succeed (as long as user.salt is not nil).
Issuer
You can also specify a name for the 'issuer' (the name of the website) where the user is using this token:
If you want to authenticate based on a model called User, then you should name your session object UserMfaSession.
# app/models/user_mfa_session.rbclassUserMfaSession < GoogleAuthenticatorRails::Session::Base# no real code needed hereend
# app/controllers/user_mfa_session_controller.rbclassUserMfaSessionController < ApplicationControllerdefnew# load your viewenddefcreateuser=current_user# grab your currently logged in userifuser.google_authentic?(params[:mfa_code])UserMfaSession.create(user)redirect_toroot_pathelseflash[:error]="Wrong code"render:newendendend
You can configure the MfaSession cookie by creating an initializer:
# config/initializers/google_authenticator_rails.rb# The cookie normally expires in 24 hours, you can change this to 1 monthGoogleAuthenticatorRails.time_until_expiration=1.month# You can override the suffix of the cookie's key, by default this is mfa_credentialsGoogleAuthenticatorRails.cookie_key_suffix='mfa_credentials'# Rails offers a few more cookie options, by default only :httponly is turned on, you can change it to HTTPS only:GoogleAuthenticatorRails.cookie_options={:httponly=>true,:secure=>true,:domain=>:all}
If you want to manually destroy the MFA cookie (for example, when a user logs out), just call
UserMfaSession::destroy
Storing Secrets in Encrypted Form (Rails 4.1 and above)
Normally, if an attacker gets access to the application database, they will be able to generate correct authentication codes,
elmininating the security gains from two-factor authentication. If the application's secret_key_base is handled more securely
than the database (by, for example, never putting it on the server filesystem), protection against database compromise can
be gained by setting the :encrypt_secrets option to true. Newly-created secrets will then be stored in encrypted form.
Existing non-encrypted secrets for all models for which the :encrypt_secrets option has been set to true
can be encrypted by running
rails google_authenticator:encrypt_secrets
This may be reversed by running
rails google_authenticator:decrypt_secrets
then by removing, or setting false, the :encrypt_secrets option.
If secret_key_base needs to change, set old_secret_key_base to the old key in config/secrets.yml before generating the new key.
Then run
rails google_authenticator:reencrypt_secrets
to change all encrypted google secret fields to use the new key.
If the app is not running under Rails version 4.1 or above, encryption will be disabled, and a warning issued if :encrypt_secrets
is enabled on a model.
If encryption is enabled for a model, the Google secret column of its table must be able to hold at least 138 characters, rather than just 16.
Contributing
Fork it
Create your feature branch (git checkout -b my-new-feature)
Commit your changes (git commit -am 'Added some feature')
Push to the branch (git push origin my-new-feature)
请发表评论