Parse.com - allow only one session per user - session

I have an App on Parse platform. What I need:
The User logs in on first device.
The User logs in on second device.
System revokes session on the first device.
I tried to remove objects from Session/Installation classes, but it did not help.
How can I do it?

Achieving this is not quite straightforward as there is no way to intercept login events or write cloud code triggers for Parse Session class. If you delete a client session record from the Session table, it should certainly revoke it and you end up getting authentication errors on that client. To achieve what you want, you need to write your own cloud function that logs a user in instead of using the SDK login function. That way you can first go through the Session table and revoke/delete any session associated with that user before logging in your user on the new device.

Related

Parse.com login using magic link

After Parse.com have introduced new revocable session that gets destroyed when a user logs out, is it possible to build a reliable login process using "magic links", ie. a user receives an email including a link, and gets logged in in a web browser after clicking that link?
Previously, sessions in Parse were long lived and implementing a magic link login process was a matter of providing the user with his/her session token and having the client call Parse.User.become(<sessionToken>).
This approach will fail with new revocable session if a user is not already signed in to the Parse server when generating and clicking a magic link, since there will not be any session to give the user that he/she can use in the call to Parse.User.become().
Any clarification if this is possible to accomplish this with the new more secure type of revocable sessions in Parse, or suggestions on how to achieve this, are welcome.

Clarifications of use of Session in Parse Dashboard

I recently noticed the addition of a "Session" object in Parse dashboard. Now, from what I understand, a session uniquely identifies a user to the server. So why would we need such a Session? For the session token? We already have a currentInstallation... so I don't really see the point. Can someone explain and provide a scenario where I would use the "Session" object. Right now they just annoy me by their presence because they take up potential space on the Parse server and I would like to go delete them all but want to make sure that isn't stupid.
The sessions are used by parse to deal with the users (is the user logged?, on which devices?, etc.), and are available as a class as you may want to manipulate them. By deleting the sessions you would automatically logout all your users, so it's a pretty bad idea.
You don't have to use or touch anything about this class, but here are few examples of why it can be useful:
[...] If a user contacts you about his or her account being compromised in your app, you can use the Data Browser, REST API, or Cloud Code to forcefully revoke user sessions using the Master Key. These new APIs also allow you build a “session manager” UI screen where your app’s users can see a list of all devices they’ve logged in with, and optionally log out of other devices. [...]
You can read more about the Sessions on their blog post.

JWT and one(!) session per user / no concurrent sessions

Our current app uses HTTP sessions and we'd like to replace that with JWT.
The setup allows only a single session per user. This means:
User signs in at Device 1
User is logged in at Device 1 (new Session created)
User signs in at Device 2
User is logged in at Device 2 (new Session created)
User is not logged in at Device 1 (Session got destroyed)
This works because there's a server-side relation between session id and user id.
Using JWT I could imagine to have some counter inside the user database, which gets increased with every login, i.e.:
User signs in at Device 1
JWT tokens signature contains counter+1 (and save new counter to database)
User signs in at Device 2
JWT's signature contains counter+1 and it gets increased and saved to db.
Now with every request I have to check if the incoming signature is correct for the current counter value.
This somehow makes it stateful. :(
But ... one of JWT's benefits is, that there's no need to access any database or session store for validating the token.
Is there some other solution for preventing concurrent logins? Maybe something that works without database access and keeps it stateless?
You are very close to the solution.
To do this you need the following:
1. Include iat in the token (Time when the token was issued)
2. Somewhere store the time when the user last logged in, for example in the user's profile.
Now when validating the token, do an extra check: iat (Issued At) must be at or later than the last login time. This implicitly invalidates older tokens.
First of all, when using JWTs for session, it's important to define:
Stateless Token: Contains all the session data inside the token. This
way you don't need to store it anywhere.
Steteful Token: Contains a session id. When the server receives the
token he will need to retrieve the information about the session.
If you are using a stateful solution in order to invalidate a token you could query the DB for the last session ID for that user and compare with the received token.
In a stateless solution, as the other answers pointed out, you will probably need to persist the state somewhere. But in comparison with a Stateful Token you only need to store a counter like you suggested or a "last_login" like #The Tahaan suggested.
If you feel that using a DB is too heavy, I recommend using an in-memory solution like Redis, which besides being very fast it has the capability of easily setting a duration for the persisted data. This way the user would have to login again if:
User signs in in another device.
A certain time elapsed.
What about closing the session of the user on any other device.
What about. every time user login, you saving the last login by type of device, and send a push notification to all the devices connected of the same type (supposedly one)?
In this case on a browser, You can send the push notification to the browser, just check what happens if that browser is closed at the moment?
In the case of mobile apps, you can send a push notification to the mobile app's with the instruction to close
This is a different solution that may be a closer fit in some situations.
You still need to go to the DB, but assuming that most of your users have only one device and only some have a second device, you can use the following strategy:
During Login (New Token Request) let the client supply a device-id. Compare this with the "last_device" value of the user. If it is different it means the user has changed to a new device.
When this happens, add an epoc entry for this user in a special table.
userid: unique reference user(id) not null
epoc: timestamp
The idea is that this table could possibly be much smaller than the full user table. Only users with more than one device logged in recently will have an entry in this table. So scanning this table is efficient. After validating the token the normal way, check that the iat (Issued At) is not before the user's session epoc. If it is, then the device is not the most recent logged in device.
This solution has other uses: It allows a user to remotely log out themselves (You create a new entry for the user with the current time which effectively invalidates all existing tokens for them).
Maintain this table by deleting items that are older than the maximum lifetime of any token regularly.
How I think it can be done.
Just create a random id (lets call this validation code) and store it in DB whenever jwt is generated.
Encode this in JWT.
whenever any request is made with jwt check if the validation code encoded in jwt matches in DB.
If user tries to login to other device it will regenerate the validation code, expiring all other sessions.

Where to fill session after authenticating via WSFederationAuthenticationModule

We are using WSFederationAuthenticationModule in an ASP.NET MVC 5 application to authenticate users via Windows Azure ACS. We have tried multiple things to save some user specific data in the session after the authentication has succeeded but everytime we write to the session object we got the exception 'Session state is not available in this context'. Our favorite was the event System.IdentityModel.Services.FederatedAuthentication.WSFederationAuthenticationModule.SignedIn but of course at this time the session does not exist. Where is the recommended place to write initial data of an currently authenticated user into the session?
Have you considered using the ClaimsAuthenticationManager for this? The beauty of this is that you can access the current claims for the authenticated user (before your application code is executed), run whatever query you need to run, and then stuff new claims into the claimset of the principal. I've used this technique before for similar situations as you described.
If you really need to get access to the session data, then I think you want to look at the SessionSecurityTokenHandler class.

Persistent Data while Logged In

I am newbie developer in mac development. What I need to do is create an authentication dialog when the user clicks the Print button in any application.
I need to store the username and password for 1 hour (to avoid authentication all the time) but this should be deleted when the user logs out from the machine.
What I am thinking is to use NSUserDefaults to store the data, and create a logout hook to delete this data. Is this the proper way of doing this?
Use Authorization Services. It sounds like your app fits the "Simple, Self-Restricted Application" model described in the guide.
When you create your authorization right, use the timeout attribute to set the length of time that the user's credentials will be cached.

Resources