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

Add support for non-revocable sessions #1392

Closed
steven-supersolid opened this issue Apr 6, 2016 · 32 comments
Closed

Add support for non-revocable sessions #1392

steven-supersolid opened this issue Apr 6, 2016 · 32 comments

Comments

@steven-supersolid
Copy link
Contributor

parse-server currently only supports revocable sessions but my live app uses legacy sessions. While there is some documentation about migrating sessions for a parse.com app, it is not clear what will happen when switching to parse-server. I would like to minimise changes when migrating my live app to parse-server.

I will do some tests on this and maybe submit a PR but have not examined the code in any detail yet. Legacy sessions could give a potential performance increase as the _Session collection would not be used in any requests.

@flovilmart
Copy link
Contributor

non revocable session have been deprecated as they are quite insecure, I'm not sure we want to get those back

@steven-supersolid
Copy link
Contributor Author

I wouldn't say insecure, just less secure in that once a token is known the account can be accessed indefinitely. This was good enough for Parse until March 2015 and I could not find an announcement about deprecation, just that they are no longer the default.

Revocable sessions were not fully supported in Unity clients until recently because Unity had a bug with HTTP errors not being handled correctly. This meant that a invalid session error would look like any other HTTP error so the client could have no special logout handling without applying it to all errors. This also meant that enabling revocable sessions with a Unity client was a risk in case Parse had an issue retrieving from _Session.

Short term, the goal for me is for my app to work with parse-server exactly the same as it works on Parse.com, and I imagine this is shared by a lot of Parse customers.

In my test, using a non-revocable session token on a Cloud Code call resulted in request.user being undefined. This can be caught and then logout/login requested on the client but login is not always straightforward. Overall this not as smooth as the background migration procedure describe in this guide: https://www.parse.com/tutorials/session-migration-tutorial

I also tested using a parse-server issued non-revocable token with a Parse.com hosted app (using the same database) and this worked fine. This means that users will at least not have to log back in if the server needs to be switched back due to a critical bug.

@ralphilius
Copy link

+1 for this since we need this to implement social login which needs to fetch user's session for become method call. Please direct me a solution if any.

http://stackoverflow.com/questions/33492263/how-to-create-a-parse-user-account-from-a-android-google-token/33631230

@hramos
Copy link
Contributor

hramos commented Apr 10, 2016

Non-revocable sessions were deprecated with the launch of revocable sessions on March 25 last year. Apps created after March 25, 2015 can only use revocable sessions.

This issue only affects apps that have not migrated to the new, more secure session model. Instead of working around it by implementing the older session model in Parse Server, we suggest following our migration guide and migrating your user sessions to the newer revocable model.

@ralphilius
Copy link

@hramos Can we login a user without knowing a password?

@flovilmart
Copy link
Contributor

@ralphilius you Can definitely write your own custom login logic through the Oauth adapters. You need 1 method to validated the authData passed through the Oauth login, and pass the ID of your 3rd party Auth. It don't have to be Oauth explicitly.

We also have oauth for Google provided by parse server. Right away.

@ralphilius
Copy link

@flovilmart I have seen the google oauth, but I don't get it how these adapters are called by clients and how they return required data (session/username & password) to clients log in. Sorry to ask but I don't get the big picture of this implementation yet.

Thanks for support.

@flovilmart
Copy link
Contributor

You have to gather the auth token and user ID on the client. Then send those through the link method. The server will validate the auth token through the Google API, and on subsequent login, match the Google user ID you provided with the one initially provided upon linking or login.

@ralphilius
Copy link

OK. For Java, I should call logInWithInBackground(String authType, Map<String,String> authData) right?

Please see this example:

String authType = "google";
Map<String, String> authData = new HashMap<>();
authData.put("access_token", "RETRIEVED_ACCESS_TOKEN");
ParseUser.logInWithInBackground(authType, authData);

I have only one doubt about the authData.id in google oauth. Is it user's email or Google Account Id?

@flovilmart
Copy link
Contributor

It should be what corresponds to the user_id returned by the API Call. Most likely the Google account ID

@flovilmart
Copy link
Contributor

@steven-supersolid
Copy link
Contributor Author

@hramos I cannot find any announcement that non-revocable sessions are deprecated. The blog post talks about revocable sessions being "Enhanced Sessions", i.e. a recommended improvement rather than a replacement. While new apps do default to revocable sessions, it is possible to switch back on the General Settings page.

Nothing will change for new apps if we add non-revocable session support and I agree that revocable sessions are a good idea and should be the default. I simply wish to add support for the existing Parse.com session handling.

@ewindso
Copy link

ewindso commented May 10, 2016

@steven-supersolid I needed this support and added a PR here: #1749

@mmarshak
Copy link

I have the same issue, I have an app that does non-revocable sessions, and per Ramos I went to the guide in - https://parse.com/tutorials/session-migration-tutorial.
In the guide for Mobile apps step 1 it says - In your app's code, handle the "invalid session token" error. See details in iOS | Android | .NET | JavaScript.
But when I click on the iOS link I get page not found.
Could you point me to the correct website with the example how to handle the invalid session ?

@flovilmart
Copy link
Contributor

What version of parse-server are you running?

@mmarshak
Copy link

I am using 2.2.18, and today I do not call [PFUser enableRevocableSessionInBackground] in my App.
I just found out that you released 2.2.19 that support on the server the call for upgradeToRevocableSession. It is not clear to me should I just upgrade the server and everything will work or do I need to call on the iOS client [PFUser enableRevocableSessionInBackground] and add in many places in my code error recovery for the error INVALID_SESSION_TOKEN which based on the documentation n the new place - https://parseplatform.github.io//docs/ios/guide/, says that I need to logout the user. Not really a nice experience to my current user of the app.
Or I just need to upgrade the server and everything will work?

function handleParseError(err) {
switch (err.code) {
case Parse.Error.INVALID_SESSION_TOKEN:
Parse.User.logOut();
... // If web browser, render a log in screen
... // If Express.js, redirect the user to the log in route
break;

... // Other Parse API errors that you want to explicitly handle

}
}

@flovilmart
Copy link
Contributor

flovilmart commented Sep 10, 2016

2.2.19 that support on the server the call for upgradeToRevocableSession

You should update to that version

need to call on the iOS client [PFUser enableRevocableSessionInBackground]

Yes you need to add that line in the app delegate up upgrade the session token, then it all should update correctly. The session token in the response should start with an r:

Then it's a good idea to handle invalid session tokens and prompt for a login as well.

@mmarshak
Copy link

Thanks.

Should I add [PFUser enableRevocableSessionInBackground] inside the block bellow as part of didFinishLaunchingWithOptions , as following -

[Parse initializeWithConfiguration:[ParseClientConfiguration configurationWithBlock:^(id<ParseMutableClientConfiguration> configuration) {
    configuration.applicationId = @"XXXXXX";
    configuration.clientKey = @"YYYY";

    configuration.server = @"ZZZZ ";

    configuration.localDatastoreEnabled = YES ;

     [PFUser enableRevocableSessionInBackground];
}]];

Also, do I still need to ask the user to logout?

If I will not add the support for handling invalid session token, will it work with 2.2.19.

@flovilmart
Copy link
Contributor

nope, the configuration block is not an async block.

Do it that way:

[Parse initializeWithConfiguration:[ParseClientConfiguration configurationWithBlock:^(id<ParseMutableClientConfiguration> configuration) {
    configuration.applicationId = @"XXXXXX";
    configuration.clientKey = @"YYYY";

    configuration.server = @"ZZZZ ";

    configuration.localDatastoreEnabled = YES ;
}]];

[PFUser enableRevocableSessionInBackground];

calling [PFUser enableRevocableSessionInBackground]; should make a call to the upgrateToRevocableSession endpoint that will in turn make the exchange between your local session token and a revocable session token. Upon success, the session should be returned to the iOS SDK and everything should be fine for your user.

@mmarshak
Copy link

It works, thank you allot for the quick help.

@flovilmart
Copy link
Contributor

Glad to know it works correctly, it wasn't tested on iOS, only with the JS SDK! Awesome!

@flovilmart
Copy link
Contributor

Closing as revocableSessionUpgrade has been implemented by #2646.

@mmarshak
Copy link

I tested it with app written in Objective-C and I use Parse Client SDK 1.14.2 if somebody care to know.

And the nice thing I did not had to add the recovery for the invalid Token, saved me a ton of time.

Nice!

@flovilmart
Copy link
Contributor

Awesome!

@mmarshak
Copy link

Hi @flovilmart,

My parse server is hosted on AWS on Elastic Beanstalk, and per our previous exchange I start calling from the new version of the iOS app [PFUser enableRevocableSessionInBackground].
I am getting now warning from AWS that says -

Message: Environment health has transitioned from Ok to Warning. 100.0 % of the requests are failing with HTTP 5xx.

I download the logs from AWS, and found that I am getting the HTTP 500 error as a result of calling
enableRevocableSessionInBackground. I see the 500 error in nginx/access.log, and in nodes.log I see other error related to the call and it complains about

I am using Parse server 2.2.19, and Parse client SDK 1.14.2.

I looked at commit 2646 that introduce enableRevocableSessionInBackground on Parse server and in SessionsRouter.js in handleUpdateToRevocableSession you access user.id when you build the sessionData. Maybe if the client app have an a anonymous user login to the app then the user.id is not defined ? In the nodes.log it complains about not defined _id.

Is it possible that the AWS NGINX load balancer see the error 500 because of this and it report it to the health monitor in AWS which then report me the 500 error and move the server to degraded mode?

Any suggestion how to fix this issue?

Bellow are the logs for the times when I am getting the 500 error-


/var/log/nginx/access.log

172.31.57.70 - - [17/Sep/2016:13:30:54 +0000] "PUT /server/classes/_Installation/cVDvKNxn7j HTTP/1.1" 200 71 "-" "MyAppName/510 CFNetwork/758.5.3 Darwin/15.6.0" "107.77.223.68"
172.31.57.70 - - [17/Sep/2016:13:32:25 +0000] "PUT /server/classes/_Installation/O0gdCix8pw HTTP/1.1" 200 71 "-" "MyAppName/510 CFNetwork/808.0.2 Darwin/16.0.0" "108.7.56.162"
172.31.18.53 - - [17/Sep/2016:13:32:28 +0000] "PUT /server/classes/_Installation/pegHJd1ULm HTTP/1.1" 200 71 "-" "MyAppName/510 CFNetwork/808.0.2 Darwin/16.0.0" "64.30.72.169"
172.31.18.53 - - [17/Sep/2016:13:32:39 +0000] "PUT /server/classes/_Installation/h58cNPGdqL HTTP/1.1" 200 71 "-" "MyAppName/510 CFNetwork/808.0.2 Darwin/16.0.0" "107.77.226.213"
172.31.57.70 - - [17/Sep/2016:13:32:40 +0000] "PUT /server/classes/_Installation/WtscPBtEM2 HTTP/1.1" 200 71 "-" "MyAppName/510 CFNetwork/758.5.3 Darwin/15.6.0" "75.68.90.83"
172.31.18.53 - - [17/Sep/2016:13:32:42 +0000] "PUT /server/classes/_Installation/5vs215XGgF HTTP/1.1" 200 71 "-" "MyAppName/510 CFNetwork/758.5.3 Darwin/15.6.0" "174.192.24.110"
172.31.57.70 - - [17/Sep/2016:13:33:07 +0000] "PUT /server/classes/_Installation/j2fvZhFU5K HTTP/1.1" 200 71 "-" "MyAppName/510 CFNetwork/808.0.2 Darwin/16.0.0" "74.104.123.65"
172.31.57.70 - - [17/Sep/2016:13:33:21 +0000] "POST /server/classes/SessionViewing HTTP/1.1" 201 64 "-" "MyAppName/510 CFNetwork/758.5.3 Darwin/15.6.0" "71.232.78.165"
172.31.57.70 - - [17/Sep/2016:13:33:21 +0000] "PUT /server/classes/_Installation/pktZIdC2Jv HTTP/1.1" 200 86 "-" "MyAppName/510 CFNetwork/758.5.3 Darwin/15.6.0" "71.232.78.165"
172.31.57.70 - - [17/Sep/2016:13:33:22 +0000] "PUT /server/classes/_Installation/pktZIdC2Jv HTTP/1.1" 200 71 "-" "MyAppName/510 CFNetwork/758.5.3 Darwin/15.6.0" "71.232.78.165"
172.31.18.53 - - [17/Sep/2016:13:33:53 +0000] "PUT /server/classes/_Installation/IEn1vQQg3e HTTP/1.1" 200 71 "-" "MyAppName/510 CFNetwork/808.0.2 Darwin/16.0.0" "174.192.29.227"
172.31.57.70 - - [17/Sep/2016:13:34:10 +0000] "POST /server/upgradeToRevocableSession HTTP/1.1" 500 45 "-" "MyAppName/510 CFNetwork/758.5.3 Darwin/15.6.0" "66.87.124.62"
172.31.57.70 - - [17/Sep/2016:13:34:10 +0000] "GET /server/config HTTP/1.1" 200 2821 "-" "MyAppName/510 CFNetwork/758.5.3 Darwin/15.6.0" "66.87.124.62"
172.31.57.70 - - [17/Sep/2016:13:34:12 +0000] "PUT /server/classes/_Installation/yUNydcAcTu HTTP/1.1" 200 71 "-" "MyAppName/510 CFNetwork/758.5.3 Darwin/15.6.0" "66.87.124.62"
172.31.18.53 - - [17/Sep/2016:13:34:43 +0000] "POST /server/events/AppOpened HTTP/1.1" 200 2 "-" "MyAppName/510 CFNetwork/758.5.3 Darwin/15.6.0" "108.26.217.154"
172.31.18.53 - - [17/Sep/2016:13:34:43 +0000] "GET /server/config HTTP/1.1" 200 2821 "-" "MyAppName/510 CFNetwork/758.5.3 Darwin/15.6.0" "108.26.217.154"


/var/log/nodejs/nodejs.log

�[31merror�[39m: Error handling request: [TypeError: Cannot read property 'id' of undefined]
�[31merror�[39m: Uncaught internal server error. [TypeError: Cannot read property 'id' of undefined] TypeError: Cannot read property 'id' of undefined
at SessionsRouter.handleUpdateToRevocableSession (/var/app/current/node_modules/parse-server/lib/Routers/SessionsRouter.js:109:25)
at /var/app/current/node_modules/parse-server/lib/Routers/SessionsRouter.js:154:23
at /var/app/current/node_modules/parse-server/lib/PromiseRouter.js:259:9
at /var/app/current/node_modules/parse-server/lib/PromiseRouter.js:295:9
at Layer.handle as handle_request
at next (/var/app/current/node_modules/express/lib/router/route.js:131:13)
at Route.dispatch (/var/app/current/node_modules/express/lib/router/route.js:112:3)
at Layer.handle as handle_request
at /var/app/current/node_modules/express/lib/router/index.js:277:22
at Function.process_params (/var/app/current/node_modules/express/lib/router/index.js:330:12)
TypeError: Cannot read property 'id' of undefined
at SessionsRouter.handleUpdateToRevocableSession (/var/app/current/node_modules/parse-server/lib/Routers/SessionsRouter.js:109:25)
at /var/app/current/node_modules/parse-server/lib/Routers/SessionsRouter.js:154:23
at /var/app/current/node_modules/parse-server/lib/PromiseRouter.js:259:9
at /var/app/current/node_modules/parse-server/lib/PromiseRouter.js:295:9
at Layer.handle as handle_request
at next (/var/app/current/node_modules/express/lib/router/route.js:131:13)
at Route.dispatch (/var/app/current/node_modules/express/lib/router/route.js:112:3)
at Layer.handle as handle_request
at /var/app/current/node_modules/express/lib/router/index.js:277:22
at Function.process_params (/var/app/current/node_modules/express/lib/router/index.js:330:12)
�[31merror�[39m: Error handling request: [TypeError: Cannot read property 'id' of undefined]
�[31merror�[39m: Uncaught internal server error. [TypeError: Cannot read property 'id' of undefined] TypeError: Cannot read property 'id' of undefined
at SessionsRouter.handleUpdateToRevocableSession (/var/app/current/node_modules/parse-server/lib/Routers/SessionsRouter.js:109:25)
at /var/app/current/node_modules/parse-server/lib/Routers/SessionsRouter.js:154:23
at /var/app/current/node_modules/parse-server/lib/PromiseRouter.js:259:9
at /var/app/current/node_modules/parse-server/lib/PromiseRouter.js:295:9
at Layer.handle as handle_request
at next (/var/app/current/node_modules/express/lib/router/route.js:131:13)
at Route.dispatch (/var/app/current/node_modules/express/lib/router/route.js:112:3)
at Layer.handle as handle_request
at /var/app/current/node_modules/express/lib/router/index.js:277:22
at Function.process_params (/var/app/current/node_modules/express/lib/router/index.js:330:12)
TypeError: Cannot read property 'id' of undefined
at SessionsRouter.handleUpdateToRevocableSession (/var/app/current/node_modules/parse-server/lib/Routers/SessionsRouter.js:109:25)
at /var/app/current/node_modules/parse-server/lib/Routers/SessionsRouter.js:154:23
at /var/app/current/node_modules/parse-server/lib/PromiseRouter.js:259:9
at /var/app/current/node_modules/parse-server/lib/PromiseRouter.js:295:9
at Layer.handle as handle_request
at next (/var/app/current/node_modules/express/lib/router/route.js:131:13)
at Route.dispatch (/var/app/current/node_modules/express/lib/router/route.js:112:3)
at Layer.handle as handle_request
at /var/app/current/node_modules/express/lib/router/index.js:277:22
at Function.process_params (/var/app/current/node_modules/express/lib/router/index.js:330:12)
�[31merror�[39m: Error handling request: [TypeError: Cannot read property 'id' of undefined]
�[31merror�[39m: Uncaught internal server error. [TypeError: Cannot read property 'id' of undefined] TypeError: Cannot read property 'id' of undefined
at SessionsRouter.handleUpdateToRevocableSession (/var/app/current/node_modules/parse-server/lib/Routers/SessionsRouter.js:109:25)
at /var/app/current/node_modules/parse-server/lib/Routers/SessionsRouter.js:154:23
at /var/app/current/node_modules/parse-server/lib/PromiseRouter.js:259:9
at /var/app/current/node_modules/parse-server/lib/PromiseRouter.js:295:9
at Layer.handle as handle_request
at next (/var/app/current/node_modules/express/lib/router/route.js:131:13)
at Route.dispatch (/var/app/current/node_modules/express/lib/router/route.js:112:3)
at Layer.handle as handle_request
at /var/app/current/node_modules/express/lib/router/index.js:277:22
at Function.process_params (/var/app/current/node_modules/express/lib/router/index.js:330:12)
TypeError: Cannot read property 'id' of undefined
at SessionsRouter.handleUpdateToRevocableSession (/var/app/current/node_modules/parse-server/lib/Routers/SessionsRouter.js:109:25)
at /var/app/current/node_modules/parse-server/lib/Routers/SessionsRouter.js:154:23
at /var/app/current/node_modules/parse-server/lib/PromiseRouter.js:259:9
at /var/app/current/node_modules/parse-server/lib/PromiseRouter.js:295:9
at Layer.handle as handle_request
at next (/var/app/current/node_modules/express/lib/router/route.js:131:13)
at Route.dispatch (/var/app/current/node_modules/express/lib/router/route.js:112:3)
at Layer.handle as handle_request
at /var/app/current/node_modules/express/lib/router/index.js:277:22
at Function.process_params (/var/app/current/node_modules/express/lib/router/index.js:330:12)
�[31merror�[39m: Error handling request: [TypeError: Cannot read property 'id' of undefined]
�[31merror�[39m: Uncaught internal server error. [TypeError: Cannot read property 'id' of undefined] TypeError: Cannot read property 'id' of undefined
at SessionsRouter.handleUpdateToRevocableSession (/var/app/current/node_modules/parse-server/lib/Routers/SessionsRouter.js:109:25)
at /var/app/current/node_modules/parse-server/lib/Routers/SessionsRouter.js:154:23
at /var/app/current/node_modules/parse-server/lib/PromiseRouter.js:259:9
at /var/app/current/node_modules/parse-server/lib/PromiseRouter.js:295:9
at Layer.handle as handle_request
at next (/var/app/current/node_modules/express/lib/router/route.js:131:13)
at Route.dispatch (/var/app/current/node_modules/express/lib/router/route.js:112:3)
at Layer.handle as handle_request
at /var/app/current/node_modules/express/lib/router/index.js:277:22
at Function.process_params (/var/app/current/node_modules/express/lib/router/index.js:330:12)
TypeError: Cannot read property 'id' of undefined
at SessionsRouter.handleUpdateToRevocableSession (/var/app/current/node_modules/parse-server/lib/Routers/SessionsRouter.js:109:25)
at /var/app/current/node_modules/parse-server/lib/Routers/SessionsRouter.js:154:23
at /var/app/current/node_modules/parse-server/lib/PromiseRouter.js:259:9
at /var/app/current/node_modules/parse-server/lib/PromiseRouter.js:295:9
at Layer.handle as handle_request
at next (/var/app/current/node_modules/express/lib/router/route.js:131:13)
at Route.dispatch (/var/app/current/node_modules/express/lib/router/route.js:112:3)
at Layer.handle as handle_request
at /var/app/current/node_modules/express/lib/router/index.js:277:22
at Function.process_params (/var/app/current/node_modules/express/lib/router/index.js:330:12)

@flovilmart
Copy link
Contributor

@mmarshak can you open an issue for that please?

@flovilmart
Copy link
Contributor

@mmarshak

Maybe if the client app have an a anonymous user login to the app then the user.id is not defined ?

The anonymous users should have a user.id set as well.

Also, ca you run with VERBOSE=1 so we have the full trace of the request/response for this error?

@mmarshak
Copy link

I opened a new issue for this #2720.

@techyrajeev
Copy link

Hi @flovilmart
Can you please tell me alternative to this in javascript parse sdk?
logInWithInBackground(String authType, Map<String,String> authData)

I want to enable google login.

@flovilmart
Copy link
Contributor

You need to use that method, with google as auth type and a map with the access token set as authData. Please refer to the documentation on the wiki, the authentication modules are pretty straightforward

@techyrajeev
Copy link

techyrajeev commented Sep 22, 2016

@flovilmart https://github.com/ParsePlatform/parse-server/wiki/OAuth
This one you are pointing about. I don't see any thing related to google login here.

Also I don't see any logInWithInBackground method https://parseplatform.github.io/Parse-SDK-JS/api/classes/Parse.User.html on the docs.
I have reached at following point I have received google auth token and data after validation. Next I don't know what to do when user is new or user is returning.
Please guide me If I am wrong.

@jbcaveman
Copy link

jbcaveman commented Jan 31, 2017

If any laggards still need that parse session migration tutorial, look here: https://web.archive.org/web/20170101001730/https://parse.com/tutorials/session-migration-tutorial

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

8 participants