Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot make Devise to log out from Angular.js

I made Devise authentication to log out via GET, but couldn't make it log out using this Angular.js code:

$scope.logout = ->
  $http.get('/users/sign_out').success ->
    #If it does not redirect from 'editor' to 'login' then you haven't actually logged out
    $location.path('editor')

Devise's logout behaviour seems to be random - sometimes it logs out, sometimes not. And if I enter /users/sign_out into browser's address bar, it logs out always.

Ok, I switched the Devise authentication's log out to POST request to get rid of caching problems and used following Angular.js code:

$scope.logout = ->
  $http.post('/users/sign_out').success ->
    $location.path('editor')

The first time it logged out fine, as always, but then I couldn't make it to log out.

I decided to make my own method to see what happens:

match '/logout' => 'api#logout', :via => :post

class ApiController < ApplicationController
  before_filter :authenticate_user!

  def logout
    sign_out
    if current_user
      puts 'Has not signed out!'
    else
      puts 'Has signed out!'
    end
    head :ok
  end
end

and detected that after sign_out the current_user is always nil, but then the Angular application by some miracle manages to access other methods of ApiController, and current_user isn't nil there!

I do not understand that. Ok, let us suppose that there may follow some other HTTP request, right after (or at the same time as) logout request, passing the authentication cookie and Devise re-logins, but shouldn't the session ID passed in cookie be expired immediately after call of sign_out method?!

like image 315
Paul Avatar asked Nov 03 '22 01:11

Paul


1 Answers

sorry I never responded earlier, hope this helps

My Sesisons Controller

$scope.signOutUser = function () {
  $http.delete('/api/users/sign_out', {
    auth_token: Session.currentUser // just a cookie storing my token from devise token authentication.
  }).success( function(result) {
    $cookieStore.remove('_pf_session');
    $cookieStore.remove('_pf_name');
    $cookieStore.remove('_pf_email');
    location.reload(true); // I need to refresh the page to update cookies
  }).error( function(result) {
    console.log(result);
  });
} 

My Devise Sessions Controller I overrode

class SessionsController < Devise::SessionsController
  before_filter :authenticate_user!, only: :destroy

  def destroy
    token = params[:auth_token]
    @user = User.find_by_authentication_token(token)
    @user.reset_authentication_token!
    sign_out(@user)
    render status: :ok, json: {message: "You have successfully logged out"}
  end
end

As you can see, I'm not using Rails cookies and thus my answer may not pertain. If I did I would probably add a line like session[:user] = nil in my destroy action.

like image 109
shicholas Avatar answered Nov 13 '22 01:11

shicholas