twilio / authy-devise Goto Github PK
View Code? Open in Web Editor NEWAuthy Devise plugin to add Two-Factor Authentication
License: MIT License
Authy Devise plugin to add Two-Factor Authentication
License: MIT License
I have integrated the authy-devise and it works well. But now i am facing a problem, in verify_authy.html.erb
there are two links for sms and phone verification
<%= authy_request_sms_link %>
<%= authy_request_phone_call_link %>
But i want that user should be able to request the verification code via email also i tried searching a lot in issues and googled it a lot but could not find anything any idea how can i achieve it
Any help is greatly appreciated thanks
The migration that is generated inherits from ActiveRecord::Migration instead of ActiveRecord::Migration[5.2].
Here is the error I get:
$ rake db:migrate
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:
Directly inheriting from ActiveRecord::Migration is not supported. Please specify the Rails release the migration was written for:
class DeviseAuthyAddToCredentials < ActiveRecord::Migration[4.2]
Easy fix on my end, but maybe the edge version should support rails 5.2?
Previously I use to validate entered API key using following method
def validate_credentials
errors.add(:api_key, I18n.t('authy.invalid_credentials')) if invalid_authy_credentials?
end
def invalid_authy_credentials?
response = Authy::API.get_request('protected/json/verify/', :api_key => self.api_key)
response.present? && response.has_key?('errors')
end
It use to work with API key for my account, but while I tried the same yesterday, it's returning '{"message"=>"Invalid API key.", "success"=>false, "errors"=>{"message"=>"Invalid API key."}}'
I even tried with newly generated API key but the result is same.
In authy initialiser I have uri set as
Authy.api_uri = 'https://api.authy.com/'
We have noticed that if there are two blocks in the Devise initializer, after you run the generator, it will insert the commented out configuration example twice. Here is the result of that in our devise initializer:
Rails.application.config.to_prepare do
# existing configuration here for devise layouts
# ==> Devise Authy Authentication Extension
# How long should the user's device be remembered for.
# config.authy_remember_device = 1.month
end
Devise.setup do |config|
# existing configuration here
# ==> Devise Authy Authentication Extension
# How long should the user's device be remembered for.
# config.authy_remember_device = 1.month
end
The second block is where the code really should be. One idea we had on how to fix this would be to use the argument :after
for inject_into_file
to specify Devise.setup do |config|
(or something similar). That way, it will always insert the code into the one correct block.
Here is some documentation that shows the use of the after
argument:
http://www.rubydoc.info/github/wycats/thor/Thor/Actions:inject_into_file
The code in question for the generator is here:
https://github.com/authy/authy-devise/blob/master/lib/generators/devise_authy/install_generator.rb#L16
Thanks!
When generating the database changes the authy_id
column should be t.integer
.
Makes the index smaller too :)
If a user resets their password using the Devise Recoverable functionality, they are logged in as soon as they provide their new password and are never asked to provide an Authy verification token.
Seems that functionality works fine. But my clients report that tokens take more than two minutes to reach out . I'm not sure whether this should be here or not but I should resolve the issue. So please let me know your thoughts.
I would like it if when the user visits the verify-token page, it would automatically send them an SMS so that the user doesn't have to click a button after entering the page. This seems similar to how gmail handles two factor authentication.
Is there a way to configure devise-authy to work this way or an easy way to add such functionality? (I imagine you can get something kind of close if you set up authy to send an authy link upon user creation but that assumes that users are allowed to use the authy app and that only happens upon account creation and not when the two factor auth expires.)
I have an existing devise powered app, and am adding authy. Following the instructions in the readme:
Configure your Devise user model:
rails g devise_authy [MODEL_NAME]
or add the following line to your User model
devise :authy_authenticatable, :database_authenticatable
I did the second, adding :authy_authenticatable
.
But the rails g devise_authy User
has the side effect of also creating the migration needed.
This is probably just a doc issue, but I'm not sure what the recommended approach is to get that migration.
Hey guys!
I'm using Rails4 with this gem and I setup everything as the documentation says, when I go to the 'enable-two-factor' URL everything works and I got redirected to the next page. When I put my pin on the form and submit, nothing happens.
I got an email from the Authy team saying that I'm making requests to the API without the country code, but it's weird since everything is setup and the forms were generated by the gem.
First off, I am unsure if this is the appropriate place to ask this question because this is not an issue with your gem, but an issue I am running into trying to remove it. Can you help me?
I've removed all traces of auth-devise manually and ran the appropriate migrations to remove authy related attributes from the users model - I can now create a new devise user no problem, but when I try to log into an existing account I hit this exception:
NoMethodError in Users::SessionsController#create
undefined method
authy_id' for #User:0x007fe4e1be2c10`
else
match = match_attribute_method?(method.to_s)
match ? attribute_missing(match, *args, &block) : super
end
end
Thank you!
how to pass on redirection path to the above action in devise_authy controller
I get the following error:
undefined method `user_verify_authy_path' for #<#<Class:0x007f73685d0380>:0x007f7387c07a18>
Hey folks, like many, we're still on Rails 3 and will be for the foreseeable. We've backported this gem to work with Rails 3, because after the upgrade (#52) this gem got a lot of important security patches that we needed too.
We're happy to share this code, and happy to turn it over for official hosting. I'm not exactly sure the best way to do that -- we could put it on our GitHub and you could link, or any other solution really. Let me know if there's interest in this and we can figure out the best way to make it available.
I have an application that lets users sign in to devise with their username + password, or with Omniauth.
After installing authy-devise
, the omniauth authentication method did not require users to enter their 2-factor token.
I was able to resolve that issue, but it got me thinking - why isn't there a way to query the user's current session to ensure that they are signed in with 2factor?
I think that in DeviseAuthyController#POST_verify_authy, a session variable should be set that indicates that a user entered a valid token.
That would allow me to add a before_filter
to the authenticated areas of my application to not only ensure that the user is signed in, but that they entered a valid 2-factor token.
This would have caught my Omniauth issue, as the users' session would not have indicated that they entered a valid 2-factor token.
I'm trying to integrate devise authy to my angular app, but for now, after login, I have to reload the app, otherwise, I get "Can't verify CSRF token authenticity" error even if I haven't enabled authy. Is there anyway to get rid of this error without reloading the app?
When I run rails g devise_authy:install
it fails.
/home/rails/testproject/.bundle/gems/gems/devise-authy-1.5.2/lib/devise-authy/rails.rb:7:in `block in ': uninitialized constant DeviseAuthy::Views (NameError) from /home/rails/testproject/.bundle/gems/gems/activesupport-4.1.1/lib/active_support/lazy_load_hooks.rb:38:in `instance_eval' from /home/rails/testproject/.bundle/gems/gems/activesupport-4.1.1/lib/active_support/lazy_load_hooks.rb:38:in `execute_hook' from /home/rails/testproject/.bundle/gems/gems/activesupport-4.1.1/lib/active_support/lazy_load_hooks.rb:28:in `block in on_load' from /home/rails/testproject/.bundle/gems/gems/activesupport-4.1.1/lib/active_support/lazy_load_hooks.rb:27:in `each' from /home/rails/testproject/.bundle/gems/gems/activesupport-4.1.1/lib/active_support/lazy_load_hooks.rb:27:in `on_load' from /home/rails/testproject/.bundle/gems/gems/devise-authy-1.5.2/lib/devise-authy/rails.rb:6:in `' from /home/rails/testproject/.bundle/gems/gems/devise-authy-1.5.2/lib/devise-authy/rails.rb:2:in `' from /home/rails/testproject/.bundle/gems/gems/devise-authy-1.5.2/lib/devise-authy/rails.rb:1:in `' from /home/rails/testproject/.bundle/gems/gems/devise-authy-1.5.2/lib/devise-authy.rb:12:in `' from /home/rails/.rvm/gems/ruby-2.1.1@global/gems/bundler-1.6.2/lib/bundler/runtime.rb:76:in `require' from /home/rails/.rvm/gems/ruby-2.1.1@global/gems/bundler-1.6.2/lib/bundler/runtime.rb:76:in `block (2 levels) in require' from /home/rails/.rvm/gems/ruby-2.1.1@global/gems/bundler-1.6.2/lib/bundler/runtime.rb:72:in `each' from /home/rails/.rvm/gems/ruby-2.1.1@global/gems/bundler-1.6.2/lib/bundler/runtime.rb:72:in `block in require' from /home/rails/.rvm/gems/ruby-2.1.1@global/gems/bundler-1.6.2/lib/bundler/runtime.rb:61:in `each' from /home/rails/.rvm/gems/ruby-2.1.1@global/gems/bundler-1.6.2/lib/bundler/runtime.rb:61:in `require' from /home/rails/.rvm/gems/ruby-2.1.1@global/gems/bundler-1.6.2/lib/bundler.rb:132:in `require' from /home/rails/testproject/config/application.rb:14:in `' from /home/rails/testproject/.bundle/gems/gems/spring-1.1.3/lib/spring/application.rb:82:in `require' from /home/rails/testproject/.bundle/gems/gems/spring-1.1.3/lib/spring/application.rb:82:in `preload' from /home/rails/testproject/.bundle/gems/gems/spring-1.1.3/lib/spring/application.rb:140:in `serve' from /home/rails/testproject/.bundle/gems/gems/spring-1.1.3/lib/spring/application.rb:128:in `block in run' from /home/rails/testproject/.bundle/gems/gems/spring-1.1.3/lib/spring/application.rb:122:in `loop' from /home/rails/testproject/.bundle/gems/gems/spring-1.1.3/lib/spring/application.rb:122:in `run' from /home/rails/testproject/.bundle/gems/gems/spring-1.1.3/lib/spring/application/boot.rb:18:in `' from /home/rails/.rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in `require' from /home/rails/.rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in `require' from -e:1:in `'
Hey, I noticed that users can't remember their device when they verify their installation, only when they perform a regular verification (remember_device
is called from POST_verify_authy
but not from POST_verify_authy_installation
).
Is there a particular reason that it is this way? Would it be insecure adding it to POST_verify_authy_installation
? If not, I can submit a PR adding this.
POST_disable_authy should delete the remember_device cookie. Here's a possible solution.
I have integrated authy-devise to my rails 3.2 application. Client asked me to enable two factor authentication once per day. Means two factor feature will be a one time per day deal. Do we have such option.
After integrating authy-devise in to our rails app we're now being asked to log in every day, which is confusing because the config looks like it should be at least every 2 weeks:
[4] pry(main)> Devise.authy_remember_device
=> 2592000 # 1.month
[6] pry(main)> Devise.remember_for
=> 1209600 # 2.weeks
Im not sure if this is a bug with authy-devise or something we're doing wrong, but I might as well ask anyway.
At the end of the check_request_and_redirect_to_verify_token
method (https://github.com/authy/authy-devise/blob/master/lib/devise-authy/controllers/helpers.rb#L53), the user is still signed in because the warden.authenticate?
in Devise's sign_in
(https://github.com/plataformatec/devise/blob/master/lib/devise/controllers/sign_in_out.rb#L10) is not super clearly named and will re-authenticate the user (https://github.com/hassox/warden/blob/master/lib/warden/proxy.rb#L113)
As a result, the user is signed in at the end of this before_filter
so a user can just change the url to a different endpoint and bypass 2fa entirely.
A quick fix is to add sign_out
to check_request_and_redirect_to_verify_token
(https://github.com/authy/authy-devise/blob/master/lib/devise-authy/controllers/helpers.rb#L53) which has some extra callbacks and will stop the user from being reauthenticated
After installing gem into a rails 5.2.0 environment I get the following error when trying to authenticate a user. This happens even after just installing the gem and not even adding anything to the User model.
If I remove the gem, login and authentication happens just fine. Not sure how to resolve this.
:22:45 PM web.1 | Can't verify CSRF token authenticity.
8:22:45 PM web.1 | method=POST path=/users/sign_in format=html controller=Devise::SessionsController action=create status=422 error='ActionController::InvalidAuthenticityToken: ActionController::InvalidAuthenticityToken' duration=136.83 view=0.00 db=0.98
8:22:45 PM web.1 | ActionController::InvalidAuthenticityToken excluded from capture: DSN not set
8:22:45 PM web.1 | ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):
8:22:45 PM web.1 | actionpack (5.2.0) lib/action_controller/metal/request_forgery_protection.rb:211:in handle_unverified_request' 8:22:45 PM web.1 | actionpack (5.2.0) lib/action_controller/metal/request_forgery_protection.rb:243:in
handle_unverified_request'
8:22:45 PM web.1 | devise (4.4.3) lib/devise/controllers/helpers.rb:255:in handle_unverified_request' 8:22:45 PM web.1 | actionpack (5.2.0) lib/action_controller/metal/request_forgery_protection.rb:238:in
verify_authenticity_token'
8:22:45 PM web.1 | activesupport (5.2.0) lib/active_support/callbacks.rb:426:in block in make_lambda' 8:22:45 PM web.1 | activesupport (5.2.0) lib/active_support/callbacks.rb:198:in
block (2 levels) in halting'
8:22:45 PM web.1 | actionpack (5.2.0) lib/abstract_controller/callbacks.rb:34:in block (2 levels) in <module:Callbacks>' 8:22:45 PM web.1 | activesupport (5.2.0) lib/active_support/callbacks.rb:199:in
block in halting'
8:22:45 PM web.1 | activesupport (5.2.0) lib/active_support/callbacks.rb:513:in block in invoke_before' 8:22:45 PM web.1 | activesupport (5.2.0) lib/active_support/callbacks.rb:513:in
each'
8:22:45 PM web.1 | activesupport (5.2.0) lib/active_support/callbacks.rb:513:in invoke_before' 8:22:45 PM web.1 | activesupport (5.2.0) lib/active_support/callbacks.rb:107:in
block in run_callbacks'
8:22:45 PM web.1 | sentry-raven (2.7.3) lib/raven/integrations/rails/controller_transaction.rb:7:in block in included' 8:22:45 PM web.1 | activesupport (5.2.0) lib/active_support/callbacks.rb:118:in
instance_exec'
8:22:45 PM web.1 | activesupport (5.2.0) lib/active_support/callbacks.rb:118:in block in run_callbacks' 8:22:45 PM web.1 | activesupport (5.2.0) lib/active_support/callbacks.rb:136:in
run_callbacks'
8:22:45 PM web.1 | actionpack (5.2.0) lib/abstract_controller/callbacks.rb:41:in process_action' 8:22:45 PM web.1 | actionpack (5.2.0) lib/action_controller/metal/rescue.rb:22:in
process_action'
8:22:45 PM web.1 | actionpack (5.2.0) lib/action_controller/metal/instrumentation.rb:34:in block in process_action' 8:22:45 PM web.1 | activesupport (5.2.0) lib/active_support/notifications.rb:168:in
block in instrument'
8:22:45 PM web.1 | activesupport (5.2.0) lib/active_support/notifications/instrumenter.rb:23:in instrument' 8:22:45 PM web.1 | activesupport (5.2.0) lib/active_support/notifications.rb:168:in
instrument'
8:22:45 PM web.1 | actionpack (5.2.0) lib/action_controller/metal/instrumentation.rb:32:in process_action' 8:22:45 PM web.1 | actionpack (5.2.0) lib/action_controller/metal/params_wrapper.rb:256:in
process_action'
8:22:45 PM web.1 | activerecord (5.2.0) lib/active_record/railties/controller_runtime.rb:24:in process_action' 8:22:45 PM web.1 | actionpack (5.2.0) lib/abstract_controller/base.rb:134:in
process'
8:22:45 PM web.1 | actionview (5.2.0) lib/action_view/rendering.rb:32:in process' 8:22:45 PM web.1 | actionpack (5.2.0) lib/action_controller/metal.rb:191:in
dispatch'
8:22:45 PM web.1 | actionpack (5.2.0) lib/action_controller/metal.rb:252:in dispatch' 8:22:45 PM web.1 | actionpack (5.2.0) lib/action_dispatch/routing/route_set.rb:52:in
dispatch'
8:22:45 PM web.1 | actionpack (5.2.0) lib/action_dispatch/routing/route_set.rb:34:in serve' 8:22:45 PM web.1 | actionpack (5.2.0) lib/action_dispatch/routing/mapper.rb:18:in
block in class:Constraints'
8:22:45 PM web.1 | actionpack (5.2.0) lib/action_dispatch/routing/mapper.rb:48:in serve' 8:22:45 PM web.1 | actionpack (5.2.0) lib/action_dispatch/journey/router.rb:52:in
block in serve'
8:22:45 PM web.1 | actionpack (5.2.0) lib/action_dispatch/journey/router.rb:35:in each' 8:22:45 PM web.1 | actionpack (5.2.0) lib/action_dispatch/journey/router.rb:35:in
serve'
8:22:45 PM web.1 | actionpack (5.2.0) lib/action_dispatch/routing/route_set.rb:840:in call' 8:22:45 PM web.1 | apartment (2.2.0) lib/apartment/reloader.rb:18:in
call'
8:22:45 PM web.1 | warden (1.2.7) lib/warden/manager.rb:36:in block in call' 8:22:45 PM web.1 | warden (1.2.7) lib/warden/manager.rb:35:in
catch'
8:22:45 PM web.1 | warden (1.2.7) lib/warden/manager.rb:35:in call' 8:22:45 PM web.1 | rack (2.0.5) lib/rack/tempfile_reaper.rb:15:in
call'
8:22:45 PM web.1 | rack (2.0.5) lib/rack/etag.rb:25:in call' 8:22:45 PM web.1 | rack (2.0.5) lib/rack/conditional_get.rb:38:in
call'
8:22:45 PM web.1 | rack (2.0.5) lib/rack/head.rb:12:in call' 8:22:45 PM web.1 | actionpack (5.2.0) lib/action_dispatch/http/content_security_policy.rb:18:in
call'
8:22:45 PM web.1 | rack (2.0.5) lib/rack/session/abstract/id.rb:232:in context' 8:22:45 PM web.1 | rack (2.0.5) lib/rack/session/abstract/id.rb:226:in
call'
8:22:45 PM web.1 | actionpack (5.2.0) lib/action_dispatch/middleware/cookies.rb:670:in call' 8:22:45 PM web.1 | activerecord (5.2.0) lib/active_record/migration.rb:559:in
call'
8:22:45 PM web.1 | actionpack (5.2.0) lib/action_dispatch/middleware/callbacks.rb:28:in block in call' 8:22:45 PM web.1 | activesupport (5.2.0) lib/active_support/callbacks.rb:98:in
run_callbacks'
8:22:45 PM web.1 | actionpack (5.2.0) lib/action_dispatch/middleware/callbacks.rb:26:in call' 8:22:45 PM web.1 | actionpack (5.2.0) lib/action_dispatch/middleware/executor.rb:14:in
call'
8:22:45 PM web.1 | actionpack (5.2.0) lib/action_dispatch/middleware/debug_exceptions.rb:61:in call' 8:22:45 PM web.1 | web-console (3.6.2) lib/web_console/middleware.rb:135:in
call_app'
8:22:45 PM web.1 | web-console (3.6.2) lib/web_console/middleware.rb:30:in block in call' 8:22:45 PM web.1 | web-console (3.6.2) lib/web_console/middleware.rb:20:in
catch'
8:22:45 PM web.1 | web-console (3.6.2) lib/web_console/middleware.rb:20:in call' 8:22:45 PM web.1 | actionpack (5.2.0) lib/action_dispatch/middleware/show_exceptions.rb:33:in
call'
8:22:45 PM web.1 | lograge (0.10.0) lib/lograge/rails_ext/rack/logger.rb:15:in call_app' 8:22:45 PM web.1 | railties (5.2.0) lib/rails/rack/logger.rb:26:in
block in call'
8:22:45 PM web.1 | activesupport (5.2.0) lib/active_support/tagged_logging.rb:71:in block in tagged' 8:22:45 PM web.1 | activesupport (5.2.0) lib/active_support/tagged_logging.rb:28:in
tagged'
8:22:45 PM web.1 | activesupport (5.2.0) lib/active_support/tagged_logging.rb:71:in tagged' 8:22:45 PM web.1 | railties (5.2.0) lib/rails/rack/logger.rb:26:in
call'
8:22:45 PM web.1 | sprockets-rails (3.2.1) lib/sprockets/rails/quiet_assets.rb:13:in call' 8:22:45 PM web.1 | actionpack (5.2.0) lib/action_dispatch/middleware/remote_ip.rb:81:in
call'
8:22:45 PM web.1 | request_store (1.4.1) lib/request_store/middleware.rb:19:in call' 8:22:45 PM web.1 | actionpack (5.2.0) lib/action_dispatch/middleware/request_id.rb:27:in
call'
8:22:45 PM web.1 | rack (2.0.5) lib/rack/method_override.rb:22:in call' 8:22:45 PM web.1 | rack (2.0.5) lib/rack/runtime.rb:22:in
call'
8:22:45 PM web.1 | activesupport (5.2.0) lib/active_support/cache/strategy/local_cache_middleware.rb:29:in call' 8:22:45 PM web.1 | actionpack (5.2.0) lib/action_dispatch/middleware/executor.rb:14:in
call'
8:22:45 PM web.1 | actionpack (5.2.0) lib/action_dispatch/middleware/static.rb:127:in call' 8:22:45 PM web.1 | rack (2.0.5) lib/rack/sendfile.rb:111:in
call'
8:22:45 PM web.1 | sentry-raven (2.7.3) lib/raven/integrations/rack.rb:51:in call' 8:22:45 PM web.1 | webpacker (4.0.0.pre.pre.2) lib/webpacker/dev_server_proxy.rb:18:in
perform_request'
8:22:45 PM web.1 | rack-proxy (0.6.4) lib/rack/proxy.rb:57:in call' 8:22:45 PM web.1 | railties (5.2.0) lib/rails/engine.rb:524:in
call'
8:22:45 PM web.1 | puma (3.11.4) lib/puma/configuration.rb:225:in call' 8:22:45 PM web.1 | puma (3.11.4) lib/puma/server.rb:632:in
handle_request'
8:22:45 PM web.1 | puma (3.11.4) lib/puma/server.rb:446:in process_client' 8:22:45 PM web.1 | puma (3.11.4) lib/puma/server.rb:306:in
block in run'
8:22:45 PM web.1 | puma (3.11.4) lib/puma/thread_pool.rb:120:in `block in spawn_thread'
Hi, would this work in conjunction with https://github.com/Houdini/two_factor_authentication ? I think that it would be great to add auty support WITH Houdini's two factor app.
This is an incorrect assumption.
And the controller runs a check with_authy_authentication?
on models that do not have :authy_authenticatable
applied, causing my app to crash.
In my app I have two types of users (e.g. Admins, Users)
In this example Admins would required authy_authenticatable
but Users don't. However, when a user tries to change a password - the call to with_authy_authentication?
is made against the user model, causing a fatal error.
If cost is a problem, I recommend using Cloudflare it's a very popular free CDN. I live in Asia, and the 59.5MB installer requires me to download for at least 2 hours.
I know this might not be the appropriate channel to discuss this, but I think this is the fastest way to reach you guys. I'm sorry for any inconveniences that this may cause you.
I have gem installed and configured in my application as per the read me.
I can verify with tokens sent to me by SMS. However, my app never appears in the list of apps set up for my Authy account on my mobile.
Am I missing some configuration issue?
I'm having trouble getting this to work with Devise and ActiveAdmin. The routes configuration we already have is:
devise_for :admin_users, ActiveAdmin::Devise.config
The routes configuration from the authy-devise readme is:
devise_for :users, :path_names => {
:verify_authy => "/verify-token",
:enable_authy => "/enable-two-factor",
:verify_authy_installation => "/verify-installation"
}
Do you have an example of how to configure authy-devise to work with Devise + ActiveAdmin?
I believe we need to call record_authy_authentication
also in the POST_verify_authy_installation
method.
def POST_verify_authy_installation
token = Authy::API.verify({
:id => self.resource.authy_id,
:token => params[:token],
:force => true
})
self.resource.authy_enabled = token.ok?
if token.ok? && self.resource.save
set_flash_message(:notice, :enabled)
redirect_to after_authy_verified_path_for(resource)
else
handle_invalid_token :verify_authy_installation, :not_enabled
end
end
We need to invoke the record_authy_authentication
after if token.ok? && self.resource.save
. This I believe will make Authy related session keys available after a successful first time installation verification.
Its possible to go around it by overriding the after_authy_verified_path_for
method call and invoking the record_authy_authentication
but I feel this needs to be grounded in the POST_verify_authy_installation
method.
The enable-two-factor page times out on form submit with the following error:
HTTPClient::ConnectTimeoutError in Devise::DeviseAuthyController#POST_enable_authy
execution expired
In preparation for using frozen string literals, the devise-authy gem needs to be updated to handle them properly.
❯❯❯ RUBYOPT="--enable-frozen-string-literal" bundle exec rails server
/Users/kevin/.rvm/gems/ruby-2.4.3@workfit/gems/bundler-1.16.1/lib/bundler/runtime.rb:84:in `rescue in block (2 levels) in require': There was an error while trying to load the gem 'devise-authy'. (Bundler::GemRequireError)
Gem Load Error is: can't modify frozen String
The value for users is that frozen literals reduce memory consumption (in some cases up to 30% depending on how heavy string usage is) and performance gain potential is there too.
The resolution in this case might be in the dependency gem httpclient
and addressable
, but also every file in the gem should make use of the frozen string literal comment.
When strings need to be mutated, there are ways to accomplish this through the use of +""
and "".dup
.
Looking at https://github.com/authy/authy-devise/blob/f3fd125f1b8c9539a1a700d3198628cf4fe332cd/lib/devise-authy/controllers/helpers.rb#L12, the remember_device cookie has no link to the current account. This makes it trivial for any attacker to bypass two-factor authentication for a compromised account, rendering authy useless:
Every time, it returns with User couldn't be found
. This is because there is nothing in the session when it is called.
I'm trying to come up with a solution. It appears that the session disappears between before filters and the handler actually being called.
I have phone calls enabled for users, however I don't know how to provide that option in the UI for my users.
In verify_authy_installation.html.erb
there is a link authy_request_sms_link
. Is there a similar helper for phone calls?
For authy_enabled users, we are seeing them be redirected to the root path, rather than the path they originally loaded (prior to authenticating).
To reproduce:
It seems to me that the default behaviour should be to redirect the user to the original path.
Is it possible to require all new users enable_authy?
Problem One
Verify token page is nicely displayed after login. However, the routes are not actually protected and I am able to access all resources here in.
Problem Two
Sign-out route isn't excluded and I am unable to logout. I get redirected to the verify token screen. Why?
Am using the latest 1.5.1 gem from git directly.
Is there something missing from the documentation that I need to do or is this just broken as of the recent release?
I am using Rails 5.1.
Whenever I enable a user for 2fa by submitting the related form on the enable_authy.html.haml
template, It just refreshes the page.
Here are the logs:
Started GET "/2fa/enable" for 127.0.0.1 at 2017-06-10 17:33:01 +0200
Processing by Devise::DeviseAuthyController#GET_enable_authy as HTML
Parameters: {"subdomain"=>""}
User Load (0.5ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 6877909168363724625 ORDER BY `users`.`id` ASC LIMIT 1
Rendering devise/devise_authy/enable_authy.html.haml within layouts/application
Rendered shared/assets/icons/ui/_close.html (0.0ms) [cache miss]
Rendered shared/components/_esc_close.html.haml (40.1ms) [cache miss]
Rendered shared/assets/icons/loaders/_button.html (0.5ms) [cache miss]
Rendered devise/devise_authy/enable_authy.html.haml within layouts/application (118.0ms)
Rendered shared/assets/icons/loaders/_saving.html (0.5ms) [cache miss]
Rendered shared/components/notifications/_notification.html.haml (42.0ms) [cache miss]
Rendered shared/components/notifications/_notification.html.haml (4.5ms) [cache miss]
Rendered shared/layouts/body/notifications/_notifications.html.haml (117.0ms) [cache miss]
Rendering layouts/base.html.haml
Rendered shared/layouts/head/analytics/_google_analytics.html.erb (0.5ms) [cache miss]
Rendered shared/layouts/head/_schema_markup.html (0.5ms) [cache miss]
Rendered layouts/base.html.haml (1319.1ms)
Completed 200 OK in 2021ms (Views: 2005.4ms | ActiveRecord: 1.5ms)
Started POST "/2fa/enable" for 127.0.0.1 at 2017-06-10 17:38:09 +0200
Processing by Devise::DeviseAuthyController#POST_enable_authy as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"Y22fjdrfZyRrlBjj9eyN4Vyi1/HYJZjV8JowXAAeVVugF86fKdh26pWrawouBrH3V4e2CSx7RjNUB7XWk37PKQ==", "country"=>"United States", "country_code"=>"us", "cellphone"=>["1234567890"], "subdomain"=>""}
User Load (0.5ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 6877909168363724625 ORDER BY `users`.`id` ASC LIMIT 1
Cookie#domain returns dot-less domain name now. Use Cookie#dot_domain if you need "." at the beginning.
Rendering devise/devise_authy/enable_authy.html.haml within layouts/application
Rendered shared/assets/icons/ui/_close.html (0.5ms) [cache miss]
Rendered shared/components/_esc_close.html.haml (39.4ms) [cache miss]
Rendered shared/assets/icons/loaders/_button.html (0.5ms) [cache miss]
Rendered devise/devise_authy/enable_authy.html.haml within layouts/application (117.9ms)
Rendered shared/assets/icons/loaders/_saving.html (0.5ms) [cache miss]
Rendered shared/components/notifications/_notification.html.haml (41.0ms) [cache miss]
Rendered shared/components/notifications/_notification.html.haml (4.5ms) [cache miss]
Rendered shared/layouts/body/notifications/_notifications.html.haml (116.0ms) [cache miss]
Rendering layouts/base.html.haml
Rendered shared/layouts/head/analytics/_google_analytics.html.erb (0.5ms) [cache miss]
Rendered shared/layouts/head/_schema_markup.html (0.5ms) [cache miss]
Rendered layouts/base.html.haml (1314.2ms)
Completed 200 OK in 2656ms (Views: 2001.6ms | ActiveRecord: 1.5ms)
I manipulated the route urls. Still, when using the default route configuration the same problem occurs.
User while trying to sign-in is asked for Verification token, but at every alternate attempt after timeout of session incorrect token gets accepted and access is granted. Inspecting session object returns
{"user_id"=>10005, "user_password_checked"=>true, "user_remember_me"=>false, "warden.user.user.key"=>[[10005], "$2a$10$P7L6AIYNYQUA18Toya1ghe"], "warden.user.user.session"=>{:with_authy_authentication=>true, :id=>10005, "last_request_at"=>2014-12-03 12:30:15 UTC}, "session_id"=>"98530de7cdf50d3682dee7dff3382958", "last_user"=>"User", "_csrf_token"=>"Y8OQt1SxuYJRUgZbBJs3Oo72AtH0I3Q/qbVCYoxnzTM="}
During a user's first session hitting my application they're prompted to enable Authy. After entering their cellphone number they're taken to the verify-installation
route which asks the user to enter their Authy token. Instead of being required to enter a token, they can navigate elsewhere in the web application and continue on as an authenticated user. This appears to only be true of that session - a user who skips entering their token at that step and attempts to log in again later or from another browser is forced to enter a token before they can access the application.
I am logging in to my application using omniauth with facebook.
I am able to successfully enable authy for a particular user. However, when I log in, I am not taken to the verify token page.
When I go to /users/verify-token manually, here is what I see in the logs.
Started GET "/users/verify-token" for 127.0.0.1 at 2014-06-19 10:58:12 -0400
Processing by Devise::DeviseAuthyController#GET_verify_authy as HTML
User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = 1 ORDER BY "users"."id" ASC LIMIT 1
Redirected to http://localhost:3000/
Filter chain halted as :find_resource_and_require_password_checked rendered or redirected
Completed 302 Found in 3ms (ActiveRecord: 0.5ms)
Just curious why the POST_disable_auth
method doesn't also call a method which can be easily overriden (ala after_authy_enabled_path_for
)?
Instead, it is hard-coded to root_path
I have setup the following in my app/controller directory:
class Custom::DeviseAuthyController < Devise::DeviseAuthyController
protected
def after_authy_enabled_path_for(resource)
new_gem_authorization_path
end
end
I restarted my Rails server and... it still redirects to root path.
I have an admin page , from which i need to enable authy for users under me.How could I do that?
In a recent project I have two classes of users, one who signs in only via an API (users) and one who signs in via a browser (admins). I had stopped warden
from storing current_user
s in the session, but adding authy-devise
, even though it was only added for admins, still broke this. It's because https://github.com/authy/authy-devise/blob/87731bec3e6bd5ecd84aa174bacec15da1f24687/lib/devise-authy/rails.rb does:
ActiveSupport.on_load(:action_controller) do
include DeviseAuthy::Controllers::Helpers
end
and that calls
included do
before_action :check_request_and_redirect_to_verify_token, :if => :is_signing_in?
end
and :is_signing_in?
calls the devise helper signed_in?
which will authenticate with warden and store it in the session 😞
This is a pain point in devise that is not unique to this gem, but could we solve some of it in this scenario by removing the attempt to verify in the following method?
def is_signing_in?
if devise_controller? && signed_in?(resource_name) &&
is_devise_sessions_controller? &&
self.action_name == "create"
return true
end
return false
end
It seems like it should be unnecessary since check_request_and_redirect_to_verify_token
is implemented as:
def check_request_and_redirect_to_verify_token
if signed_in?(resource_name) &&
warden.session(resource_name)[:with_authy_authentication] &&
require_token?
# login with 2fa
id = warden.session(resource_name)[:id]
remember_me = (params.fetch(resource_name, {})[:remember_me].to_s == "1")
return_to = session["#{resource_name}_return_to"]
sign_out
session["#{resource_name}_id"] = id
# this is safe to put in the session because the cookie is signed
session["#{resource_name}_password_checked"] = true
session["#{resource_name}_remember_me"] = remember_me
session["#{resource_name}_return_to"] = return_to if return_to
redirect_to verify_authy_path_for(resource_name)
return
end
end
FWIW, I personally got around this by implementing the following in my ApplicationController
:
def is_signing_in?
if request.format.json?
false
else
super
end
end
YMMV.
<%= link_to '?', '#', :id => 'authy-help' %>
Seems to do nothing
I'm struggling with this for 2 days. I have 3 types of members using STI and I'm managing each permission of each user with the CanCan gem. After I added the this gem, it generated a few more controller methods but I need to manage them with CanCan and I don't know how.
I need to block the authy routes for 2 types of members and allow to the other one.
I've gotten everything working on Rails 5. One thing I've noticed is that disabling the device via the authy dashboard has not effect on logins. The users are still able to login from disabled devices.
Is this normal?
Authy supports custom texts through custom_message
curl 'https://api.authy.com/protected/json/phones/verification/start?api_key=XXX' \
-d via='sms' \
-d phone_number='111-111-1111' \
-d country_code=1 \
-d custom_message='Your phone verification pin for Owl Bank is {{code}}'curl 'https://api.authy.com/protected/json/phones/verification/start?api_key=XXX' \
-d via='sms' \
-d phone_number='111-111-1111' \
-d country_code=1 \
-d custom_message='Your phone verification pin for Owl Bank is {{code}}'
I expected this to work like this:
= authy_request_sms_link(:custom_message => t('views.authy.security_code'))
However it doesn't do anything.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.