Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

seeing other users data after login/out with different users on ionic #375

Closed
abhayastudios opened this issue Sep 11, 2015 · 20 comments
Closed

Comments

@abhayastudios
Copy link

I've run into what seems to me to be a pretty serious issue. I've got devise as well as device_token_auth setup side-by-side, as well as ng-token-auth for the ionic front-end. When logging in/out with different users everything is working fine as long as I login using regular devise or in my ionic project with ng-token-auth in a regular browser (localStorage is used for storing the tokens).

However, when running the ionic project on an android phone, when I log in through a first user and then out, then login with a second user I still see the first user's data. Looking at the rails logs I see that for some requests actually the id of the previous user is used when using current_user.id in the query.

First the user logs in and the correct user id is select (id=20), so far so good:

2015-09-11T17:05:00.418741+00:00 app[web.1]: Started POST "/api/v1/auth/sign_in" for <IP> at 2015-09-11 17:05:00 +0000
[...]
2015-09-11T17:05:00.848609+00:00 app[web.1]:   User Load (4.4ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 FOR UPDATE  [["id", 20]]

Then immediately after login, ui-router invokes another state and another request is made using this query in the controller with current_user.id:

@votables = Votable.joins("LEFT JOIN votes ON votes.votable_id = votables.id AND user_id = #{current_user.id}").where("votes.id is NULL")

This triggers the following query for getting the current_user details:

2015-09-11T17:05:01.432071+00:00 app[web.1]: Started GET "/api/v1/votes.json" for <IP> at 2015-09-11 17:05:01 +0000
[...]
2015-09-11T17:05:01.448617+00:00 app[web.1]:   User Load (1.9ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1  ORDER BY "users"."id" ASC LIMIT 1  [["id", 18]]

As you can see here somehow the results for another user with id=18 are returned instead of the expected details for user with id=20!!

The strange thing is that in parallel to this query I update the account with a token I received from the ionic platform that does use the right user id:

2015-09-11T17:05:03.542369+00:00 app[web.1]: Started PUT "/api/v1/auth" for <IP> at 2015-09-11 17:05:03 +0000
2015-09-11T17:05:04.115428+00:00 app[web.1]:   User Load (14.2ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 FOR UPDATE  [["id", 20]]

Even stranger to me is that, when I look at the request headers that the ionic app is sending to devise_token_auth for both these last two queries, that the client and access-token headers are exactly the same. I understand that this is to be expected due to the batch_request_buffer_throttle setting. However, I really don't understand how two queries with the exact same tokens can result in a different user id on the server side. BTW these tokens are the ones that were sent in the response to the sign_in request.

I will continue to try and research this myself but I would love some guidance with what seems to me to be a serious bug.

Thanks!

@abhayastudios abhayastudios changed the title seeing other users data when after login/out with different users on ionic seeing other users data after login/out with different users on ionic Sep 11, 2015
@abhayastudios
Copy link
Author

I see now that even before the sign in a request is being made by the client to validate the token from what I assume is the previous session:

Started GET "/api/v1/auth/validate_token" for <IP> at 2015-09-12 01:29:26 +0300
Processing by DeviseTokenAuth::TokenValidationsController#validate_token as HTML
  User Load (0.5ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ?  ORDER BY "users"."id" ASC LIMIT 1  [["id", 18]]

So my guess is that the source of this token is not properly updated on cordova/ionic after a sign_in. I'll try to trace it tomorrow.

@ianchen06
Copy link

@abhayastudios I'm having the exact same issue! After a previously logged in User1 logged out, User2 will get authenticated back in with User1's session!! Except I'm using a React.js frontend with j-toker.

This is a really serious issue, I'm also searching for ways to solve it...

@abhayastudios
Copy link
Author

@ianchen06 does it happen to you also in a cordova/ionic project only? are you testing on android/iphone?

@ianchen06
Copy link

@abhayastudios I have not tested it on mobile yet, but it seems to be related to this pull request?

#200

@lynndylanhurley Have you seen others reporting this issue? Thanks

@abhayastudios
Copy link
Author

When I run 'clear data' on android for the ionic application then the next login will work ok until I login with another user, so it is definitely something with the localStorage.

@ianchen06 what storage are you using? cookies (default) or localStorage?

@hparfr
Copy link

hparfr commented Sep 14, 2015

I'm using cookies and have also this issue (2nd user get previous user data).
From my understanding, there is two issues :

  • sign_out doesn't delete the cookies related to session handling
  • sign_out doesn't invalidate theses tokens

@stephenbaidu
Copy link

I have same issue in my angular web app. I just don't know what to do for my users. Some of my users access the same computer and things have become a real big mess. Manually deleting the _app_session before signing in with another user seems to resolve the issue but, they can't go on this path. Hope we get a solution soon.

@stephenbaidu
Copy link

I've currently reverted to version 0.1.31 which works just fine.

@makarakao
Copy link

I also had the same problem with logging user using email and oauth on the same device. In my rails console, I got this warning message, "Can't verify CSRF token authenticity", when trying to sign user out.

Started DELETE "/api/v1/auth/sign_out" for xxx.xxx.x.xxx at 2015-10-02 00:24:42 +0700
Processing by Users::SessionsController#destroy as JSON
Can't verify CSRF token authenticity

To solve my problem, I added :destroy in the exception in my session controller.

####################
#app/controllers/users/sessions_controller.rb
class Users::SessionsController < DeviseTokenAuth::SessionsController
protect_from_forgery except: [:create, :destroy]

def create
super
end

def resource_params
params.permit(devise_parameter_sanitizer.for(:sign_in), :format, :session)
end

end
####################

And from client side I need to invalidate tokens after successfully sign out.

####################
$auth.signOut()
.then(function(resp) {
$auth.invalidateTokens();
})
.catch(function(resp) {
// handle error response
});
####################

After that, everything is fine.

@mikeorr85
Copy link

+1 to @stephenbaidu. I was experiencing this problem on a mobile project and reverting back 0.1.31 fixed it.

@stephenbaidu
Copy link

@mikeorr85 I also had to peg devise itself at 3.5.1 in order to resolve the error nameError (uninitialized constant DeviseTokenAuth::Concerns::User::BCrypt) which occurred in production.

@ryankc33
Copy link

Had the same problem. Turns out Rails CSRF protection prevented devise token auth from destroying the session:

Processing by Users::SessionsController#destroy as JSON
Can't verify CSRF token authenticity

solved by:
STEP 1: Installed the ng-rails-csrf library to resolve csrf error
https://github.com/xrd/ng-rails-csrf/blob/master/vendor/assets/javascripts/ng-rails-csrf.js

STEP 2: Calling $auth.invalidateTokens() after $auth.signOut() as per @makarakao

@mikeorr85
Copy link

Glad I took a second look at this. I was able to get passed my trouble while upgrading back to the latest version (0.1.36) simply by overriding the sessions controller as @makarakao originally posted.

routes.rb

  mount_devise_token_auth_for 'User', at: 'auth', controllers: {
    sessions: 'devise_token_auth_overrides/sessions'
  }

controllers/devise_token_auth_overrides/sessions_controller.rb

module DeviseTokenAuthOverrides
  class SessionsController < DeviseTokenAuth::SessionsController
    protect_from_forgery except: [:create, :destroy]
  end
end

@lynndylanhurley
Copy link
Owner

Can you guys please try out version 0.1.37.beta1 and see if this has been resolved?

@mikeorr85
Copy link

0.1.37.beta1 resolves the problem for me, and I no longer needed to override the SessionsController.

@lynndylanhurley
Copy link
Owner

That's great! Thx @mikeorr85!!

@mikeorr85
Copy link

Absolutely. Thank you for maintaining the gem!

@abhayastudios
Copy link
Author

@lynndylanhurley

I can confirm that with 0.1.37.beta2 the issue is resolved!! WOOHOO :)

Thanks a lot!

@lynndylanhurley
Copy link
Owner

😃

@maltem-za
Copy link

maltem-za commented Apr 26, 2018

Fast-forward to 2018 and I had the same issue with version 0.1.42 in an Angular app (no Ionic involved though) - thanks to @makarakao and @ryankc33 I noticed that I was also getting the "Can't verify CSRF token authenticity" warning message.

Adding the except: [:create, :destroy] exception in the SessionsController did fix it, but I wanted to fix the actual root cause (being the failed CSRF token check). ng-rails-csrf did not work for me (I could see a token in the request headers but it still failed validation), however angular_rails_csrf did work.

Note that you need to include ActionController::RequestForgeryProtection and ActionController::Cookies in your non-auth-related controller (base)class(es) in order for angular_rails_csrf to work, though you can leave out the latter if you explicitly exclude a class using exclude_xsrf_token_cookie.

In my case I didn't have to call $auth.invalidateTokens().

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants