Giter VIP home page Giter VIP logo

authy-devise's Introduction

🚨🚨🚨

This library is no longer actively maintained. The Authy API has been replaced with the Twilio Verify API. Twilio will support the Authy API through November 1, 2022 for SMS/Voice. After this date, we’ll start to deprecate the service for SMS/Voice. Any requests sent to the API after May 1, 2023, will automatically receive an error. Push and TOTP will continue to be supported through July 2023.

Learn more about migrating from Authy to Verify.

Please visit the Twilio Docs for:

Please direct any questions to Twilio Support. Thank you!

🚨🚨🚨


Authy Devise Build Status

This is a Devise extension to add Two-Factor Authentication with Authy to your Rails application.

Pre-requisites

To use the Authy API you will need a Twilio Account, sign up for a free Twilio account here.

Create an Authy Application in the Twilio console and take note of the API key.

Demo

See this repo for a full demo of using authy-devise.

Getting started

First get your Authy API key from the Twilio console. We recommend you store your API key as an environment variable.

$ export AUTHY_API_KEY=YOUR_AUTHY_API_KEY

Next add the gem to your Gemfile:

gem 'devise'
gem 'devise-authy'

And then run bundle install

Add Devise Authy to your App:

rails g devise_authy:install

--haml: Generate the views in Haml
--sass: Generate the stylesheets in Sass

Configuring Models

You can add devise_authy to your user model in two ways.

With the generator

Run the following command:

rails g devise_authy [MODEL_NAME]

To support account locking (recommended), you must add :authy_lockable to the devise :authy_authenticatable, ... configuration in your model as this is not yet supported by the generator.

Manually

Add :authy_authenticatable and :authy_lockable to the devise options in your Devise user model:

devise :authy_authenticatable, :authy_lockable, :database_authenticatable, :lockable

(Note, :authy_lockable is optional but recommended. It should be used with Devise's own :lockable module).

Also add a new migration. For example, if you are adding to the User model, use this migration:

class DeviseAuthyAddToUsers < ActiveRecord::Migration[6.0]
  def self.up
    change_table :users do |t|
      t.string    :authy_id
      t.datetime  :last_sign_in_with_authy
      t.boolean   :authy_enabled, :default => false
    end

    add_index :users, :authy_id
  end

  def self.down
    change_table :users do |t|
      t.remove :authy_id, :last_sign_in_with_authy, :authy_enabled
    end
  end
end

Final steps

For either method above, run the migrations:

rake db:migrate

[Optional] Update the default routes to point to something like:

devise_for :users, :path_names => {
	:verify_authy => "/verify-token",
	:enable_authy => "/enable-two-factor",
	:verify_authy_installation => "/verify-installation",
	:authy_onetouch_status => "/onetouch-status"
}

Now whenever a user wants to enable two-factor authentication they can go to:

http://your-app/users/enable-two-factor

And when the user logs in they will be redirected to:

http://your-app/users/verify-token

Custom Views

If you want to customise your views, you can modify the files that are located at:

app/views/devise/devise_authy/enable_authy.html.erb
app/views/devise/devise_authy/verify_authy.html.erb
app/views/devise/devise_authy/verify_authy_installation.html.erb

Request a phone call

The default views come with a button to force a request for an SMS message. You can also add a button that will request a phone call instead. Simply add the helper method to your view:

<%= authy_request_phone_call_link %>

Custom Redirect Paths (eg. using modules)

If you want to customise the redirects you can override them within your own controller like this:

class MyCustomModule::DeviseAuthyController < Devise::DeviseAuthyController

  protected
    def after_authy_enabled_path_for(resource)
      my_own_path
    end

    def after_authy_verified_path_for(resource)
      my_own_path
    end

    def after_authy_disabled_path_for(resource)
      my_own_path
    end

    def invalid_resource_path
      my_own_path
    end
end

And tell the router to use this controller

devise_for :users, controllers: {devise_authy: 'my_custom_module/devise_authy'}

I18n

The install generator also copies a Devise Authy i18n file which you can find at:

config/locales/devise.authy.en.yml

Session variables

If you want to know if the user is signed in using Two-Factor authentication, you can use the following session variable:

session["#{resource_name}_authy_token_checked"]

# Eg.
session["user_authy_token_checked"]

OneTouch support

To enable Authy push authentication, you need to modify the Devise config file config/initializers/devise.rb and add configuration:

config.authy_enable_onetouch = true

Generic authenticator token support

Authy supports other authenticator apps by providing a QR code that your users can scan.

To use this feature, you need to enable it in your Twilio Console

Once you have enabled generic authenticator tokens, you can enable this in devise-authy by modifying the Devise config file config/initializers/devise.rb and adding the configuration:

config.authy_enable_qr_code = true

This will display a QR code on the verification screen (you still need to take a user's phone number and country code). If you have implemented your own views, the QR code URL is available on the verification page as @authy_qr_code.

Rails 5 CSRF protection

In Rails 5 protect_from_forgery is no longer prepended to the before_action chain. If you call authenticate_user before protect_from_forgery your request will result in a "Can't verify CSRF token authenticity" error.

To remedy this, add prepend: true to your protect_from_forgery call, like in this example from the Authy Devise demo app:

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception, prepend: true
end

Running Tests

Run the following command:

$ bundle exec rspec

Notice: Twilio Authy API’s Sandbox feature will stop working on Sep 30, 2021

Twilio is discontinuing the Authy API’s Sandbox, a feature that allows customers to run continuous integration tests against a mock Authy API for free. The Sandbox is no longer being maintained, so we will be taking the final deprecation step of shutting it down on September 30, 2021. The rest of the Authy API product will continue working as-is.

This repo previously used the sandbox API as part of the test suite, but that has been since removed.

You will only be affected if you are using the sandbox API in your own application or test suite.

For more information please read this article on how we are discontinuing the Twilio Authy sandbox API.

Copyright

Copyright (c) 2012-2021 Authy Inc. See LICENSE.txt for further details.

authy-devise's People

Contributors

agronv avatar alfie-max avatar barendt avatar chytreg avatar crm114 avatar dcu avatar dedene avatar dependabot[bot] avatar eliotsykes avatar flyerhzm avatar gasparila avatar grampelberg avatar heroinbob avatar jirapong avatar juliancheal avatar lucasvidal avatar mikerogers0 avatar mstruebing avatar muan avatar nukturnal avatar othercroissant avatar petergoldstein avatar philnash avatar ruragamer avatar senekis avatar simonmorley avatar thejchap avatar timeemit avatar vargasx avatar yhirano55 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

authy-devise's Issues

Not enabling user for 2fa

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.

Rails 4.2.5

I get the following error:

undefined method `user_verify_authy_path' for #<#<Class:0x007f73685d0380>:0x007f7387c07a18>

Can't verify CSRF token authenticity

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'

Require Authy

Is it possible to require all new users enable_authy?

Authy confirmation not working

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.

authy-devise adds a call to `warden.authenticate?` before all application actions

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_users 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.

Authy + Devise + ActiveAdmin

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?

User is not asked to verify auth token when logging in with Facebook via omniauth

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)

Remember device only called for verification

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.

Devise-Authy assumes that every user model will be an authy enabled one

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.

Entered API key is always returned as Invalid

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/'

`request_sms` isn't working

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.

Generated migration not completely compatible for rails 5+ apps

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?

Disabled device still allowed to login

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?

Install docs for existing user models don't create migration

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.

authy_id should be an int

When generating the database changes the authy_id column should be t.integer.
Makes the index smaller too :)

Delayed tokens

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.

Store something that indicates user is signed in with 2-factor

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.

Verification code via email not via otp or call

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

Accepting incorrect Token while signing in

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="}

Time based authentication

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.

Can you guys wrap a CDN around the S3 installers download links

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.

Link for phone call

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?

How can I define the text for the verification sms?

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.

post login redirects not handled as they would normally be by devise

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:

  • log out
  • try to access a URL that is requires auth (e.g. /my/secret/path)
  • get redirected to login
  • enter authy token
  • get redirected to the root URL (not /my/secret/path)

It seems to me that the default behaviour should be to redirect the user to the original path.

Interest in backport to Rails 3?

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.

Authy Authentication Not Recorded After Success Install Verification

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.

It should send an SMS immediately when showing verify-token page

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.)

Devise.remember_for and Devise.authy_remember_device not being respected since integrating authy

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.

Integrate CanCan with the controller actions

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.

Install failed. "uninitialized constant DeviseAuthy::Views"

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 `'

Custom redirect path does not work

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.

Removing authy-devise

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 methodauthy_id' for #User:0x007fe4e1be2c10`

else
match = match_attribute_method?(method.to_s)
match ? attribute_missing(match, *args, &block) : super
end
end

Thank you!

It's possible to bypass Authy during the installation session

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.

devise-authy modifies strings unsafely

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.

remember_device not account specific

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:

  1. Attacker logs into their account with their username and password and two-factor authentication (this will give the attacker a valid remember_device cookie)
  2. Attacker logs out
  3. Attacker logs in to compromised account. Since the cookie is still set, require_token? will return false

Generator's Use of `inject_into_file` Is Not Specific Enough

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!

Timeout on enable two-factor authentication

The enable-two-factor page times out on form submit with the following error:

HTTPClient::ConnectTimeoutError in Devise::DeviseAuthyController#POST_enable_authy
execution expired

Authy completely by passable

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

Session is reset

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?

Why doesn't my app show up in Authy on my cellphone

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?

Doesn't actually work / protect routes

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?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.