simple_token_authentication icon indicating copy to clipboard operation
simple_token_authentication copied to clipboard

Current_user is nil in destroy action - session's controller

Open sasikumargn opened this issue 7 years ago • 4 comments

Hi, I'm using simple token authentication with devise gem. current_user is set on session's controller create action and the same current_user is nil in destroy action. I'm getting current_user is nil and user_signed_in? as false in destroy action.

I'm using rails5, simple_token_authentication (1.15.1), devise (4.2.1) with angularjs.

Here is my code snippets. I'm trying to figure this out from last 2 days. Please help me out.

class ApplicationController < ActionController::API
  include ActionController::RequestForgeryProtection
  include ActionController::MimeResponds
  # before_action :authenticate_user!
  before_action :authenticate_user_from_token!
  before_action :configure_permitted_parameters, if: :devise_controller?
  acts_as_token_authentication_handler_for User, fallback_to_devise: false

  private

  def authenticate_user_from_token!
    # Set the authentication params if not already present
    if user_token = params[:user_token].blank? && request.headers["X-User-Token"]
      params[:user_token] = user_token
    end
    if user_email = params[:user_email].blank? && request.headers["X-User-Email"]
      params[:user_email] = user_email
    end

    user_email = params[:user_email].presence
    user       = user_email && User.find_by_email(user_email)

    # Notice how we use Devise.secure_compare to compare the token
    # in the database with the token given in the params, mitigating
    # timing attacks.
    binding.pry
    if user && Devise.secure_compare(user.authentication_token, params[:user_token])
      sign_in user, store: false
    end
  end

  protected

  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [:first_name, :last_name, :zipcode])
  end
end
class Api::V1::Users::SessionsController < Devise::SessionsController
  # before_action :require_no_authentication, :only => [:create ]
  skip_before_filter :verify_authenticity_token, only: [:create, :destroy], :raise => false
  skip_before_action :verify_signed_out_user, only: [:destroy]
  acts_as_token_authentication_handler_for User
  respond_to :json

  def create
    respond_to do |format|
       format.any(*navigational_formats) { super }
       format.json do
         self.resource = warden.authenticate!(auth_options)
         sign_in(resource_name, resource)
         //current_user is present at this point
         respond_with_authentication_token(resource)
       end
    end
  end

  def destroy
   // current_user is nil and user_signed_in? return's false.
    if user_signed_in?
      current_user.update_attributes(authentication_token: nil)
      render :json => {message: "sign out successfully", success: true, status: 200}
    else
      render :json => {message: "No user found", success: false, status: 404}
    end
  end

  protected

  def respond_with_authentication_token(resource)
    render json: {user: resource, message: I18n.t("devise.sessions.signed_in"), success: true, status: 200}
  end

  private

  def set_headers(resource)
    response.headers['X-User-Token'] = resource.authentication_token
    response.header['X-User-Email'] = resource.email
  end
  
end

routes.rb

root to: "home#index"

  devise_for :users, path: "api/v1/users", controllers: {
    :registrations      => 'api/v1/users/registrations',
    :sessions           => 'api/v1/users/sessions',
    :passwords          => 'api/v1/users/passwords',
    :confirmations      => 'api/v1/users/confirmations'
  }

Note: I've edited the comment slightly to add fenced code blocks. -- GB

sasikumargn avatar Apr 19 '17 05:04 sasikumargn

Hi @sasikumargn

I have the same issue.If you still don't figure it out.You try this solution. You can use session in the destroy method. The is the content of session {"session_id"=>"foo", "user_return_to"=>"/", "_csrf_token"=>"bar", "warden.user.user.key"=>["User", [18], "xxx"]} As you can see you 18 is the id of current_user.

Hopeful it would help.

yyandrew avatar Aug 11 '17 11:08 yyandrew

were you able to solve the problem? if so please share your solution.

Ibr4him avatar Jan 30 '18 15:01 Ibr4him

Found the reason why it's failing. I was using sending in the header "X-User-Token" and "X-User-Email". I changed those headers to "user_token" and "user_email" with the corresponding values and it worked !

urzur avatar May 12 '18 22:05 urzur

@sasikumargn @Ibr4him I'm not sure, if you guys found a solution to this. But I faced this is in Rails 5.2.3, the way I was able to solve this was by adding the following lines in application.rb.

config.middleware.use ActionDispatch::Cookies config.middleware.use ActionDispatch::Session::CookieStore, key: '__your_app_session'

kedarnag138 avatar Apr 10 '19 04:04 kedarnag138