parse-community / parse-server

Parse Server for Node.js / Express
https://parseplatform.org
Apache License 2.0
20.87k stars 4.78k forks source link

invalid session token code=209, message=invalid session token on v2.3.7 #3655

Closed mman closed 7 years ago

mman commented 7 years ago

Issue Description

I have started getting the error invalid session token code=209, message=invalid session token after upgrading to 2.3.7 earlier today. Looking at now closed bug #2255 and at the source code the root cause seems to be that there are two session ids present for the same user and same installation id created and updated around the same time.

Not all API calls generate this error and not all users are affected.

Steps to reproduce

Not sure, I'm continuously updating parse-server every few weeks to keep with the latest releases, the message started popping up after upgrading to 2.3.7.

Logs/Trace

This is one of the requests that generates the error message:

d61952fe52b4[1182]: #033[36mverbose#033[39m: REQUEST for [PUT] /xxx/classes/_User/HngzyE3Clx: {
d61952fe52b4[1182]:   "runCount": {
d61952fe52b4[1182]:     "__op": "Increment",
d61952fe52b4[1182]:     "amount": 1
d61952fe52b4[1182]:   },
d61952fe52b4[1182]:   "lastContact": {
d61952fe52b4[1182]:     "iso": "2017-03-21T12:01:55.180Z",
d61952fe52b4[1182]:     "__type": "Date"
d61952fe52b4[1182]:   }
d61952fe52b4[1182]: } method=PUT, url=/xxx/classes/_User/HngzyE3Clx, host=xxx, connection=close, content-length=109, x-parse-app-display-version=4.0.2, x-parse-application-id=unused, accept=*/*, x-parse-os-version=9.3.5 (13G36), accept-language=en-us, x-parse-client-key=unused, user-agent=XXX/348 CFNetwork/758.5.3 Darwin/15.6.0, x-parse-app-build-version=348, content-type=application/json; charset=utf-8, x-parse-session-token=r:97ee17db8bc95ad6b657abb84aec39cb, x-parse-client-version=i1.14.2, x-parse-installation-id=bcf5b055-3b1c-4dc2-a405-5e04a5a1c3ad, accept-encoding=gzip, deflate, __op=Increment, amount=1, iso=2017-03-21T12:01:55.180Z, __type=Date
d61952fe52b4[1182]: #033[36mverbose#033[39m: RESPONSE from [PUT] /xxx/classes/_User/HngzyE3Clx: {
d61952fe52b4[1182]:   "response": {
d61952fe52b4[1182]:     "runCount": 76,
d61952fe52b4[1182]:     "updatedAt": "2017-03-21T12:01:55.668Z"
d61952fe52b4[1182]:   }
d61952fe52b4[1182]: } runCount=76, updatedAt=2017-03-21T12:01:55.668Z
d61952fe52b4[1182]: #033[31merror#033[39m: invalid session token code=209, message=invalid session token

This is the query for all sessions for that user

rs0:PRIMARY> db.getCollection('_Session').find({"_p_user":"_User$HngzyE3Clx"})
{ "_id" : "4sQEyDhudw", "_session_token" : "r:e7500d9da1f7ea868e0e21c14b9cd83e", "_p_user" : "_User$HngzyE3Clx", "createdWith" : { "action" : "login", "authProvider" : "password" }, "restricted" : false, "expiresAt" : ISODate("2018-01-03T09:29:19.181Z"), "installationId" : "2b907a0c-26eb-4f19-bd6b-8dd7a734ec0c", "_created_at" : ISODate("2017-01-03T09:29:19.182Z"), "_updated_at" : ISODate("2017-01-03T09:29:19.182Z") }
{ "_id" : "Hn4AKvsUHi", "_session_token" : "r:e5e605f07e51c57de3e4601d3245aa34", "_p_user" : "_User$HngzyE3Clx", "createdWith" : { "action" : "login", "authProvider" : "password" }, "restricted" : false, "expiresAt" : ISODate("2018-01-03T09:29:19.201Z"), "installationId" : "2b907a0c-26eb-4f19-bd6b-8dd7a734ec0c", "_created_at" : ISODate("2017-01-03T09:29:19.202Z"), "_updated_at" : ISODate("2017-01-03T09:29:19.202Z") }
{ "_id" : "NwZxUuYmZt", "_session_token" : "r:3f9876c47dd44257afafed29c9203fd9", "_p_user" : "_User$HngzyE3Clx", "createdWith" : { "action" : "login", "authProvider" : "password" }, "restricted" : false, "expiresAt" : ISODate("2018-01-04T10:35:34.458Z"), "installationId" : "710680df-6519-42be-a675-d0dab62cdee5", "_created_at" : ISODate("2017-01-04T10:35:34.458Z"), "_updated_at" : ISODate("2017-01-04T10:35:34.458Z") }
{ "_id" : "SbwP8G7jDQ", "_session_token" : "r:f8b307985b8c4ebed1330202aa30594a", "_p_user" : "_User$HngzyE3Clx", "createdWith" : { "action" : "login", "authProvider" : "password" }, "restricted" : false, "expiresAt" : ISODate("2018-01-04T10:35:34.453Z"), "installationId" : "710680df-6519-42be-a675-d0dab62cdee5", "_created_at" : ISODate("2017-01-04T10:35:34.453Z"), "_updated_at" : ISODate("2017-01-04T10:35:34.453Z") }
{ "_id" : "BVMouretHK", "_session_token" : "r:25d3e52c371386b56e96d0f9b839c287", "_p_user" : "_User$HngzyE3Clx", "createdWith" : { "action" : "login", "authProvider" : "password" }, "restricted" : false, "expiresAt" : ISODate("2018-01-05T01:30:30.838Z"), "installationId" : "bcf5b055-3b1c-4dc2-a405-5e04a5a1c3ad", "_created_at" : ISODate("2017-01-05T01:30:30.838Z"), "_updated_at" : ISODate("2017-01-05T01:30:30.838Z") }
{ "_id" : "iHVJWkOFsV", "_session_token" : "r:97ee17db8bc95ad6b657abb84aec39cb", "_p_user" : "_User$HngzyE3Clx", "createdWith" : { "action" : "login", "authProvider" : "password" }, "restricted" : false, "expiresAt" : ISODate("2018-01-05T01:30:30.864Z"), "installationId" : "bcf5b055-3b1c-4dc2-a405-5e04a5a1c3ad", "_created_at" : ISODate("2017-01-05T01:30:30.864Z"), "_updated_at" : ISODate("2017-01-05T01:30:30.864Z") }
{ "_id" : "SxZux6gBcs", "_session_token" : "r:748b0629fad3537c64bdff4f16eb66b6", "_p_user" : "_User$HngzyE3Clx", "createdWith" : { "action" : "signup", "authProvider" : "password" }, "restricted" : false, "installationId" : "c48adf7f-7b67-4a68-a7b0-91422c3141d2", "expiresAt" : ISODate("2018-01-03T09:25:13.906Z"), "_created_at" : ISODate("2017-01-03T09:25:13.906Z"), "_updated_at" : ISODate("2017-01-03T09:25:13.906Z") }
{ "_id" : "wVY87z45Rd", "_session_token" : "r:1aaa34b479dbc40a98b92895fde3c210", "_p_user" : "_User$HngzyE3Clx", "createdWith" : { "action" : "login", "authProvider" : "password" }, "restricted" : false, "expiresAt" : ISODate("2018-02-23T13:12:54.912Z"), "installationId" : "ee8b543c-3108-43ef-85e8-383614581082", "_created_at" : ISODate("2017-02-23T13:12:54.912Z"), "_updated_at" : ISODate("2017-02-23T13:12:54.912Z") }
{ "_id" : "YQ8jGPOkdy", "_session_token" : "r:501c602c40834ef82637300847ce0d3d", "_p_user" : "_User$HngzyE3Clx", "createdWith" : { "action" : "login", "authProvider" : "password" }, "restricted" : false, "expiresAt" : ISODate("2018-02-23T13:12:55.494Z"), "installationId" : "ee8b543c-3108-43ef-85e8-383614581082", "_created_at" : ISODate("2017-02-23T13:12:55.494Z"), "_updated_at" : ISODate("2017-02-23T13:12:55.494Z") }

If you look at the session for installation id bcf5b055-3b1c-4dc2-a405-5e04a5a1c3ad they are actually just few milliseconds apart which looks weird...

{ "_id" : "BVMouretHK", "_session_token" : "r:25d3e52c371386b56e96d0f9b839c287", "_p_user" : "_User$HngzyE3Clx", "createdWith" : { "action" : "login", "authProvider" : "password" }, "restricted" : false, "expiresAt" : ISODate("2018-01-05T01:30:30.838Z"), "installationId" : "bcf5b055-3b1c-4dc2-a405-5e04a5a1c3ad", "_created_at" : ISODate("2017-01-05T01:30:30.838Z"), "_updated_at" : ISODate("2017-01-05T01:30:30.838Z") }
{ "_id" : "iHVJWkOFsV", "_session_token" : "r:97ee17db8bc95ad6b657abb84aec39cb", "_p_user" : "_User$HngzyE3Clx", "createdWith" : { "action" : "login", "authProvider" : "password" }, "restricted" : false, "expiresAt" : ISODate("2018-01-05T01:30:30.864Z"), "installationId" : "bcf5b055-3b1c-4dc2-a405-5e04a5a1c3ad", "_created_at" : ISODate("2017-01-05T01:30:30.864Z"), "_updated_at" : ISODate("2017-01-05T01:30:30.864Z") }

Please let me know if you need more details.

RafaRuiz commented 7 years ago

to me it was a endpoint called getCountries, a random one. Usually it affects all of them

flovilmart commented 7 years ago

Do you have the code for that 'random' endpoint?

RafaRuiz commented 7 years ago
Parse.Cloud.define("getCountries", function(request, response) {
    var query = new Parse.Query("Pais");
    query.limit(1000);
    query.descending("priority");
    query.find({
        success: function(result) {
            response.success(result);
        },
        error: function(error) {
            response.error(error);
        }
    });
});
flovilmart commented 7 years ago

Was it the find or the call that was yielding the invalid session? What SDK was making the call? I'd love to get closure on that issue. AFAICT, i can't design a repro case.

RafaRuiz commented 7 years ago

Yeah, that example is an dead end. That call was made from Android, iOS and Javascript, do you need the version specifically of each one?

RafaRuiz commented 7 years ago

I don't know if it's the call yielding the invalid session, I'm not sure if I understand the question

flovilmart commented 7 years ago

I'm trying to narrow down the surface of the issue, trying to understand if it comes with a particular SDK or all etc...

mman commented 7 years ago

@flovilmart I have some time this week to spend on this. I have forked the official repo and added couple debugging statements but I need your help explaining to me how to base my custom app on my own github.com based parse-server fork. Updating my custom server's package.json to point towards my forked repo does not work as it seems that plain npm install is not enough to correctly build parse-server dependency.

What's the easiest and proper way to use my custom forked parse-server as a dependency??

Thanks

flovilmart commented 7 years ago

So, because we're using babel to transpile the code and the src folder is skipped from package.json, this requires a bit of work on your side.

Local développement:

  1. Fork Parse-server
  2. Clone locally
  3. Go to the clone
  4. Link the local clone with npm link

This will let you use your copy of parse-server locally, while you're developing your instrumentation.

Deploy with your fork

  1. In your Parse-server fork folder
  2. Remove the line with lib/ from .gitignore
  3. Make your changes
  4. Run npm run build
  5. Push your branch to your fork

In your project:

Replace the parse server dependency with a github URL

mman commented 7 years ago

Thanks @flovilmart, that's precisely what I needed, running my own version with additional debugging info on one of the cluster nodes. Will update the bug once I collect something useful

flovilmart commented 7 years ago

Let me know how it goes ;)

mman commented 7 years ago

So I have caught some errors finally:

Trace: Auth.js: line 61: results wrong: sessionToken: 'CS2lrdWm5kB8afEv8IchXNlob'
     at /parse/node_modules/parse-server/lib/Auth.js:76:17
     at process._tickDomainCallback (internal/process/next_tick.js:135:7)

It indeed appears as non-revocable session token and the good news is that it's just one and the same token everywhere. Looks like one super old buggy version somewhere out in the wild. I guess we are coming to and end and we can safely close this issue... I'll think if I can somehow improve the logging here, perhaps adding HTTP request that triggered this..

flovilmart commented 7 years ago

I could indeed add additional logging when this gets triggered

flovilmart commented 7 years ago

But that's great news for you indeed :)

mman commented 7 years ago

It's excellent news indeed as it is only one user that is triggering it and it apparently does not have any side effect :). Feel free to close this issue.

mman commented 7 years ago

Thanks for all helps with this, I'm watching parse-server closely and learning hoping I can contribute more in the future as well :)

flovilmart commented 7 years ago

Awesome, that makes we think we need to beef up the debugging capabilities of parse-server so we spend less time debugging those issues.

RafaRuiz commented 7 years ago

So, what's the early solution for this? Since it's closed, I assume there's a workaround to do

flovilmart commented 7 years ago

As per @mman debugging, it seems that the invalid session token is yielded by an old, non revocable session token on a single user and therefore, not fixable server side.

RafaRuiz commented 7 years ago

Would it be good to remove all elements for sessionToken if clients are prepared to ask for a login again then ?

flovilmart commented 7 years ago

What do you mean by that?

RafaRuiz commented 7 years ago

Drop the _SessionToken collection, basically (since it could contain old session tokens) and start again from 0 items

flovilmart commented 7 years ago

Yeah, you can do that if you like, but I don't think it should be done by the server :)

RafaRuiz commented 7 years ago

No no, of course, I'll just drop the collection and check my script if it still has that problem.

Samigos commented 6 years ago

If I drop the _Session collection, will the users be logged out?