Search code examples
ruby-on-railsdevisetwiliotwo-factor-authenticationauthy

Customizing the views in authy-devise


I am trying to implement two factor authentication via authy 2FA of twilio using devise-authy gem.

I want to customize the views with three pages for 2FA.

  1. first page - My login page where user enters username and password, on submit it will be redirected to a page

  2. Second page - In this page he can select the 2FA method to receive the code via phone or sms after which he is redirected

  3. Third page - Here he finally enters the code.

I am able to configure the first two pages.

My PROBLEM is that in the third page, where i am setting up the authy form for code verification, I am getting error undefined method id for nil class

<%= verify_authy_form do %>
  <legend><%= I18n.t('submit_token_title', {:scope => 'devise'}) %></legend>
  <%= label_tag :token %>
      <%= text_field_tag :token, "", :autocomplete => :off, :id => 'authy-token' %>
  <label>
  <%= check_box_tag :remember_device %>
      <span><%= I18n.t('remember_device', {:scope => 'devise'}) %></span>
  </label>

  <!-- Help tooltip -->
  <!-- You need to configure a help message. -->
  <!-- See documentation: https://github.com/authy/authy-form-helpers#help-tooltip -->
  <!-- <%= link_to '?', '#', :id => 'authy-help' %> -->

  <%= authy_request_sms_link %>
  <%= authy_request_phone_call_link %>
  <%= submit_tag I18n.t('submit_token', {:scope => 'devise'}), :class => 'btn' %>
<% end %>

I am getting error in this line verify_authy_form On inspecting the code of gem i found that i need @authy_id so i tried <%@authy_id=User.find(session[:user_id]).authy_id%> in view no still no success.

This is my Users::AuthyCustomController, where i have overridden some of the methods as stated in gem

class Users::AuthyCustomController  < 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

def authentication_sms    
end

def authentication_phone
  @authy_id=User.find(session[:user_id]).authy_id
  # redirect_to user_verify_authy_path
  # redirect_to user_verify_authy_path and return
end
end

I have googled, but I was not able to find a solution


Solution

  • I am getting error undefined method id for nil class

    This is the form helper

    def verify_authy_form(opts = {}, &block)
      opts = default_opts.merge(:id => 'devise_authy').merge(opts)
      form_tag([resource_name, :verify_authy], opts) do
        buffer = hidden_field_tag(:"#{resource_name}_id", @resource.id)
        buffer << capture(&block)
      end
    end
    

    I belive that @resource is nil so when it does @resource.id triggers the error

    I believe this form is managed from this controller action

    # verify 2fa
    def POST_verify_authy
      token = Authy::API.verify({
        :id => @resource.authy_id,
        :token => params[:token],
        :force => true
      })
    
      if token.ok?
        @resource.update_attribute(:last_sign_in_with_authy, DateTime.now)
    
        session["#{resource_name}_authy_token_checked"] = true
    
        remember_device if params[:remember_device].to_i == 1
        if session.delete("#{resource_name}_remember_me") == true && @resource.respond_to?(:remember_me=)
          @resource.remember_me = true
        end
        sign_in(resource_name, @resource)
    
        set_flash_message(:notice, :signed_in) if is_navigational_format?
        respond_with resource, :location => after_sign_in_path_for(@resource)
      else
        handle_invalid_token :verify_authy, :invalid_token
      end
    end
    

    and you can prove that by checking and including the relevant output from rake routes. So maybe you should debug that two pieces of code, the controller action is responsible to feeding @resource to the form