I'm using the Unity API. I let a user delete their own account. It's accomplished via ParseUser.CurrentUser.DeleteAsync()
I then call ParseUser.CurrentUser.LogoutAsync(); to delete the local ParseUser object on their device.
This works, but afterwards, the now-deleted user's session is still up, buty the associated user field is now a broken link.
How can I end this session? I tried to get a reference to the session before deleting the user via ParseSession session = ParseSession.GetCurrentSessionAsyn(), deleting the user, and then the session, but the session.DeleteAsync() fails.
Edit (clarification):
I check all Tasks that return from my various function calls. I detect when things fail, and that's how I know my ParseSessions aren't being deleted (plus, they're showing up in Parse's CORE session list).
I just can't find a way to make sure the session is ended from the client's side.
DeleteAsync returns a Task Object. Try using that object to ensure that the deletion has completed prior to calling LogoutAsync()
Related
While working on a game, we needed to enforce that each user has at most one active session in one installation.
Ideally if an user tried to login while they had another active session, we should stop the login process and prompt them to what they prefer: continue the login and possibly lose unsaved data from the old session, or abort the login and keep the old session active.
However, in order to view the user's sessions, we need to log them in first. This important for security reasons, and is totally fine since a priori we should be able to do something like this:
Log the user in.
In an "afterLogin" trigger, check to see if there are any old active sessions from different installations.
If there are, abort the login (logging them out) with a particular error code/message.
Upon receiving this error code, the app could prompt the user, asking which session they prefer keeping.
The user may abort the login, in which case we should do nothing, or they may decide to use this new session, in which case we could send a login request passing an extra parameter to indicate we're forcing a new session.
We log the user in again, and since we received this extra parameter, the "beforeLogin" trigger would know to revoke and delete any old sessions.
The problem is that, obviously, there are no "beforeLogin" and "afterLogin" triggers. There's also no way to pass extra parameters to the login request.
We can work around this by calling a cloud function that handles the sessions in the login success callback in the app... but then it's easy to think of scenarios where an user ends up fully logged in with two sessions from two different installations, and we end up having to deal with them.
We also thought of logging them in via a cloud function, but that too seemed to bring more problems rather than solving them.
Is there any better way to do this?
Passport by default allows the same user to login from multiple browsers and have unique sessions created. How can I configure it to destroy the first session when the user tries to create a second session?
Currently I'm using the 'Sessions' model to add the username to the record and upon subsequent login check by username if the sessions exists. But this increases traffic to the db. I'm thinking express must be doing it already or made to, keep the 'logged in users' information in memory so that the process can be simplified. I'd be thankful for ideas around how to achieve tweak with express for this purpose or any other workaround/suggestion.
Much thanks!
I saw that at least 4 users upvote this question, so I decided to create passport-strategy for that. The new strategy called passport-one-session-per-user. It's open source strategy you can access here: https://github.com/AminaG/passport-one-session-per-user
How to use it? add it right after session. For example:
app.use(passport.session())
var passportOneSessionPerUser=require('passport-one-session-per-user')
passport.use(new passportOneSessionPerUser())
app.use(passport.authenticate('passport-one-session-per-user'))
Not need for settings, or configuration.
How it is works?
The strategy, created an array that contain serializaed user objects, and sessionID.
Every time user logged in, the strategy check if the user already logged in. If so, it's flag the other session. The next time the user in the other session make a request, the strategy see the flag, and log the user out.
I'm thinking express must be doing it already or made to, keep the 'logged in users' information in memory so that the process can be simplified.
I believe the session model loggs the user in, and saves only that logged-in-ness in the session cookie. The server itself has no clue about who is logged in, but just checks this state in the (signed) session cookie provided by the browser.
You can write your own Passport.js strategy to handle it differently.
My app creates a PFUser in order to differentiate each sending devices. I am not using PFUser.enableautomaticuser() for some technical reason.
Also, I am using local datastore by calling Parse.enableLocalDatastore()
When internet is down and app fails to sign up using
user.signUpInBackgroundWithBlock()
it won't save this user locally either. The created PFUser is discarded, calling PFUser.currentUser() returns nil.
Then how to cache created user locally when internet is unavailable? Thank you very much!
I ended up using PFUser.enableautomaticuser() and then make changes to PFUser.currentUser().
At last I will attempt to signUp, if failed, I will call saveEventually() so that next user logs in. They will retain the previous PFUser reference, so that their information won't be lost in case the user starts the application without internet.
Now the user have many roles in his privilege, I shall allow him click href and play as another role in a new window. each role has its own session.
Since the browser open window can not open with new session, I must find a way in server side.
But request doesn't support request.createSession or request.setSession(new Session()), how can i seprate a new session for this use case?
You can create a new session by HttpSession#invalidate old one but you can not retain the old one. May the following points help you
You've mentioned that each role has its own session
When user clicks a role, invalidate current session (also role) and new session would be created
Provide a link to go back his previous role if necessary
If he go backs to previous role, repeat step 2.
You have no support from tomcat. You have to this yourself.
The next strategy will NOT work on clustered tomcat. No guarantees here.
to change to a new session
Walk the session attributes via getAttributeNames() and getAttribute(String) Adding them all to a HashMap.
Serialize the HashMap into a tempfile or a static concurrent map as something you can access latter. Also store the current HttpServletRequest.getRequestURL() for latter redirection. You have to serialize.
Walk the session attributes again and removeAttribute(String) them all.
Add the key to access the file or concurrent map to the session.
Redirect the user to a login page or add synthetically all authorizations needed to the session.
to revert to old session
Check if the user has a key to access the old session. If he or she does, de-serialize the HashMap.
If the de-serialization works, walk the session and removeAttribute(String) everything
Walk the HashMap and setAttribute(String, Object) on the session.
Redirect the user to the URL stored somehow on step 2.
I'm too lazy to write the code and test it myself but I think this will work.
My web application requires a user to be logged in to view any webpage on it.
When a user logs in I store, in sessions, their username and password for retrieval later on. This all works fine but, if I rerun my project it seems to skip past authentication and go straight to the controller for that action.
What I presume is happening is that FormsAuthentication.SetAuthCookie(userName, createPersistentCookie); is remembering that the user is logged in but my sessions aren't updated.
How can I trap this scenario and update my sessions accordingly?
There are many ways of going about it.
First, you can choose, not to persist the cookie. But this will still cause the exception if the session has not expired and you recompile your project. Recompiling the project destroys the session state.
Though putting the password in session state is not the preferred way of going about it, I am sure you would have a valid reason of doing it that way.
However, if you want to do it that way, you can override the Application_AuthenticateRequest event in Global.asax. This event fires every time a request comes in and you can check if the request is authenticated (using HttpContext.Current.User.Identity.IsAuthenticated) and repopulate the session state.
By the way, can you elaborate why you need to store the user password in session state?
If I am correctly understood the issue,you can have base action class so and move the authentication mechanism there.So for every request this base will be invoked so you can make sure that the authentication mechanism is not skipped.