How to logout user after disconnect or browser close? - javascript

I'm trying to work a solution to timing out a user from my web application. I'm currently using ng2-idle and it seems to only work on the active window rather than be tracked server side (angular server webpack)
I need to handle these two events in addition to the one above:
On Browser Close
On Connection loss (Power cut, blue screen, etc..)
After testing, my timeout was not being tracked after closing the window. Ng2-idle has modules such as keepalive but I'm not exactly sure how to use it and if it solves my problem
I will provide code if needed
thank you

The main problem is, that the client and server are communicating in stateless manner. This means if the user disconnects no body knows.
If your browser has a hook function for closing or navigating to another site you could use that and send the logout request.
Another thing which relavant is session expiration, you should use that. If you are using a token you will need to blacklist that, as non active as long as the session may be valid (or however).
Disconnect is a major problem (session expiration tried to solve that somehow).
A more sophisticated way if it is really crucial to log out on disconnect you may need to use websockets or http long polling. You would need to send a heartbeat and if it's not responding, after some time you will automatically logout the user.
Hope these thoughts kind somehow help.

when you close your browser session will destroy.So you can use session to logout.

Related

How do I detect when a user closes their browser?

I am trying to set something up in my application so that I can detect if two users are editing the same document at the same time. The best way I could think to do this was by sending information to the backend when a user logs in and logs out, and checking that when I want to see if two users are active at the same time. Starting the application is easy to detect with useEffect, but I'm having trouble finding a way to do so cleanly.
I looked at the onunload and onbeforeunload, but those don't seem to have universal browser support, and I'd prefer to not disrupt the user experience with a popup. I was thinking about checking for idle, but if there's a cleaner method, such as something with Google Cloud Platform, that would be helpful. Thanks!
That sounds like a great use case for onDisconnect. You can read more about it here and here.
This would be a simple example:
var ref = firebase.database().ref("onlineState");
ref.onDisconnect().set(false);
What happens here is that this command is send to Firebase and lives there. When you lose connection to Firebase it will be executed. It doesn't matter if it's done by closing the browser/tab etc...
If you need a more complex code execution then attach a firebase cloud function trigger to those changes. It's importand to know that you can't execute client side code on that event.

How to logout open browser windows

I have a javascript/node application that uses cookies to authenticate users to the site. I need to be able to logout users even if their browser window is still open.
I can make their cookies invalid on the server... but that does not log them out until they click on some link in the site, or close their browser window. I need to be able to instantly kick them off the site even while their browser window is still open. Any ideas?
You can try setting up websocket connections. Websockets are basically duplex channels that don't require long polling. Essentially they only communicate when something needs to be done, on either end. For your situation the client side of the websocket connections would listen for specific messages from the server and the application would then react to those changes; in your case it could force a log out.
I cant understand if you want to redirect them after a while or redirect them after they logout.
If the case is such that you want to end the session after a while, you could set te maxAge of the cookie in order to last the maximum time you want your users to be able to interact with your site.
Here is an article about maxAge and expires: HTTP Cookies: What's the difference between Max-age and Expires?
Also, you could set a function that set a time out and next, if you have something like Express-sessions and passaport, you could use the logout(). But I dont recomend this. I think that is better to set the maxAge of the cookies and let the vainilla do their best.
In every case, you could use some helper in your routes that check if there is an active session. This way you could redirect them if the cookie has caducate.
Sorry aboutmy english :)
You need 3 things: mouse movements and keyboard actions, a timer, log out redirect.
check for mouse movements and keyboard actions;
if there's no activity, you start a timer;
when the time is over you redirect the user to logout url;
If you make their cookies invalid on the server, then simply force a refresh with window.location.reload(). Here's the SO question concerning that.
Here's an example I am currently using on one of my projects:
if(getCookie("id") == ""){
window.location.href = "login";
}
Put that right after the body tag for each of your pages.
Then when you expire the cookie...
expireCookie("id");
window.location.reload();
Since you've essentially deleted the cookie, the first script will now redirect the user to the login page.

Websocket with AngularJS/Asp.net

I had a specific questin about angularjs with websocket. I currently have an application that utilizes a websocket to communicate with a server, this is all nice and dandy - and when I move around pages in angular the websocket persists throughout all of the routes which is neat. Unfortunately the problem is that if the user refreshes the page (for some dumb reason), the websocket disconnects. I was wondering what the best method of handling this is. Should I just have an alert when the user tries to refresh, can I somehow detect that the websocket is closed when the page is refreshed and start a new one? I'm just wondering what the best practice for something like this is.
Thanks
There is nothing you can do, if the user refreshes, it is like restarting an application, all the bootstrapping happens again and connections are created again.
You can use javascript:onbeforeunload to warn the user that if refreshes or leaves he will lose the connection. But your users will hate your for that, it is very annoying.
Consider as well, that the user may open several tabs.
Starting a new connection is the best way. Just make sure that the user can somehow recover his context. If there is a different context per tab, then you will have to put a connectionID parameter in the URL to persist it through refreshes, and if the context is per user session, then a cookie with the session ID will do.

How to manage connexion with IndexedDb in Single Page Application

I'm trying to understand how to work properly with IndexedDb and one thing I can't understand is how are we supposed to manage the connection.
When I started playing with IndexedDb, I created a connection once the page is loaded and let it open. So the same connection was used with every request to the database until the page was reloaded.
Letting a connection open seemed like a bad practice (which is what I want to confirm) so I changed my code to open the connection only when needed (when retrieving data for example) and close it immediately after.
It doesn't feel like the API was supposed to be used that way as I felt like fighting it when modifying my code (which might simply be because I have not yet fully understood how to work with it).
Can someone please explain to me the best practice when working with IndexedDb ?
I don't really have a best practice about it, but when you are working with databases on a server you mostly close the connection when the action is completed, and you open one for every action you want to do. In the library I builded to wrap the indexedDB I also choose to open and close the db connection for every action. That way I'm sure that no connections stay open, and it gives me the flexibility to change the db structure without having to worry about all the open connections.
What are the issues you are suffering with when opening and closing the db connection for every call?

Socket.io receives messages before browser navigates to new page

I'm having an issue with Socket.io receiving messages just before a page navigation happens - generally when the message is a direct result of some server-side action triggered by the navigation.
What I'm seeing right now looks like this:
Socket.io connects
User triggers a page navigation (submits a form, refreshes, etc.)
Server-side logic sends a request to the socket.io server, which immediately dispatches the event to the still-connected client
The client receives and confirms the request (I'm pretty sure there's some confirmation of messages built-in to socket.io, correct me if I'm wrong), and would display a notification to the user, but then ...
The socket.io connection closes on the original page
The new page loads and displays
Socket.io opens a new connection, but there's no new messages, because the last one was received and confirmed.
This isn't really a bug, per se, since I don't think it's reasonable to expect Socket.io to close the connection in advance of a navigation occurring. However, I'm not really sure what the best way to handle this is. Currently I keep one connection open per-client at a time, and close the other when a new one connects. This doesn't happen in this case though, since the first one has closed before the second one connects. I also could keep a list of all clients, but that wouldn't solve this problem either, because the message would still be received by the first connection.
Can someone suggest a solution to this problem that would ensure the user always sees a notification for the message?
Socket.io tracks logical connections with its own session IDs. If you watch the console when a client connects, you'll see the IDs:
info - handshake authorized Q9syoIK47JI7dACYpxiA
What's important to understand is that those IDs are per-page, and completely separate from HTTP sessions. The Socket.io client library simply holds its session ID in a JavaScript variable. Therefore, upon navigation, the ID is obviously lost.
So, upon navigation, this happens:
User is on a page connected to sio session 1.
We begin navigation to new page. On window.onbeforeunload, Socket.io initiates a synchronous XHR request to tell the server it is disconnecting. If it succeeds, the session (1) is immediately terminated; otherwise, the session will eventually time out.
A new page is loaded. It will connect to the Socket.io server and be assigned a new session ID, 2.
Anything you send to session 1 will obviously not be delivered since our client is now connected to session 2.
With the base Socket.io functionality, it is impossible to distinguish between a user who navigates between pages and a new user. In either case, the user will connect to a new Socket.io session.
Without knowing exactly how your app works or what you're trying to accomplish, it's hard to give a definitive recommendation for solving your problem.
Most likely, what you need to be able to do is associate a Socket.io session with the user's HTTP session. You can store notifications in a queue in the user's session, and delete them when they are displayed. There are two ways of doing this:
Since you're doing a full page load, you can send queued notifications directly down with the page itself. Delete the queue when you've successfully rendered.
On a new Socket.io connection, send unread notifications over the socket. Give .emit a callback function – this is the confirmation of delivery that Socket.io provides you. When delivery is confirmed, you can delete the notification queue from the user's HTTP session.
Simplest solution: Use the onbeforeunload event to disconnect socket.io.
I verified with a HTTP debugger that this event fires before the browser issues the request (at least in Chrome) so if socket.io is disconnected here, it won't receive any messages meant for the following page.
window.onbeforeunload = function() {
socket.disconnect();
};
I haven't tested this in multiple browsers, so it might not be a perfect solution, but it seems to solve the problem for now.

Categories