simple_token_authentication
simple_token_authentication copied to clipboard
Current_user is nil in destroy action - session's controller
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
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.
were you able to solve the problem? if so please share your solution.
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 !
@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'