I have multipage application and I need to check if user was alredy open an app in other browser tab or in other browser window (IE8) and avoid this (logout user in opened new window/tab)
I use JSP, JavaScript and jQuery
If its real - not to use sessionStorage
EDITED
I also use iframes and IE8 modal dialogs.
You'd need to use a technology like SignalR that keeps a connection open. Then you'd need to ping the connections to see if that user is connected and close out their existing connection. If that implementation is too daunting, you can add a timer loop to your app/page that calls the logins table (or whatever storage device for these events) and if there are new logins, calls its own logout procedure.
One approach would be to maintain a map (in memory or in db based on user count) in your application scope which stores username vs session-id. On every login, you lookup in this map if already a session exist for that username. If exist, invalidate existing session, else store the new session-id in map. [not tested]
you can pass the the user session id or random generated id to global/window variable, ie;
window.state = 'SomeLoginIdString';
keep the state in some other variable where you client pages can easily access, preferably a datastore on client.
var loginAccessCurrentState = 'SomeLoginIdString';
When use open/switch pages compare both, if it false you can redirect to a 404 page.
loginAccessCurrentState === window.state
The idea is you only pass the state during login session, if user open a new tab, the state is undefined by default.
For single page applications the following way could be an easy solution:
Create a random ID on the entry page, store it in the session and in the GUI
On each Ajax call add the random ID to the request as additional HTTP header
if the ID does not match between given header and session, the application was opened in another tab/window and this call is coming from the "old" tab
the resulting answer of the server must then lead the GUI to lock / close itself in the affected tab
Related
I recently moved from the deprecated gapi.auth2 to the new Google Identity Services, using the javascript client library, and noticed a big difference: if someone signs in, and then reloads the page, the session is lost, and has to sign in again, every time the page is loaded. This was not the case with the deprecated library.
The problem can be easily reproduced with the Calendar API example.
Is there any configuration option to keep the session persistent? Or do I need to store the access tokens somehow? I could not find anything relevant in the official docs.
UPDATE:
The migration guide states the following:
Previously, Google Sign-In helped you to manage user signed-in status using:
Callback handlers for Monitoring the user's session state.
Listeners for events and changes to signed-in status for a user's Google Account.
You are responsible for managing sign-in state and user sessions to your web app.
However there's absolutely no information on what needs to be done.
UPDATE 2
To be more specific, the actual issue is not making the session persistent. Managing the sign in state and user session is something I can solve.
The real problem is the access token used to call the Google APIs.
As mentioned in the comments, the access tokens are 1) short lived 2) are not stored anywhere, so even if not expired, they do not persist between page reloads.
Google provides the requestAccessToken method for this, however even if I specify prompt: '', it opens the sign-in popup. If I also specify the hint option with the signed in user's email address, than the popup opens, displays a loading animation briefly, and closes without user interaction. I could live with this, however this only works if triggered by a user interaction, otherwise the browser blocks the popup window, meaning that I cannot renew the token without user interaction, e.g. on page load. Any tips to solve this?
I faced all the same issues you described in your question.
In order to help:
Google 3P Authorization JavaScript Library: in this link we can check all the methods the new library has (it does not refresh token, etc..)
This doc says the library won't control the cookies to keep the state anymore.
Solution
Firstly I need to thanks #Sam O'Riil answer.
As Sam described: "you can somehow save access token and use it to speed-up things after page reload."
Given the the Google's exampe, we should call initTokenClient in order to configure the Google Auth and the requestAccessToken to popup the auth:
tokenClient = google.accounts.oauth2.initTokenClient({
client_id: 'YOUR_CLIENT_ID',
scope: 'https://www.googleapis.com/auth/calendar.readonly',
prompt: 'consent',
callback: tokenCallback
});
tokenClient.requestAccessToken({prompt: ''})
In your tokenCallback you can save the credentials you get somehow, e.g.:
const tokenCallback(credentials) => {
// save here the credentials using localStorage or cookies or whatever you want to.
}
Finally, when you restart/reload your application and you initialize the gapi.server again, you only need to get the credentials again and set token to gapi, like:
gapi.load('client', function() {
gapi.client.init({}).then(function() {
let credentials = // get your credentials from where you saved it
credentials = JSON.parse(credentials); // parse it if you got it as string
gapi.client.setToken(credentials);
... continue you app ...
}).catch(function(err) {
// do catch...
});
});
Doing it, your application will work after the reload. I know it could not be the best solution, but seeing what you have and the library offers, I think that's you can do.
p.s.: the token expires after 1 hour and there is no refresh token (using the implicit flow) so, you will have to ask the user to sign-in again.
I am developing a enterprise application using spring and struts. But, i'm getting issue on Tab close. how to force user logging out when close the browser tab or open same page on another tab.
i have been try using onbeforeunload but i am getting issue when application running on mobile browser. and i also have seen following sample but No one has clear explanation.
How to kill session when user closed the browser without logout
How to Detect Browser Window /Tab Close Event?
is there any solution to achieve this problem using javascript or from server?
Thanks
Finally I found a solution that worked!
When the user logs in I use sessionStorage to store that a user has been logged in:
sessionStorage.setItem('logged', true)
SessionStorage will hold that property until the tab or the browser closes.
So inside the application, I check if the SessionStorage still holds that property. If not then I logout the user and I redirect him to the login.
if (!sessionStorage.getItem('logged')) {
localStorage.removeItem('token')
navigator.sendBeacon('api/logout')
window.location.replace("/login") //redirect to login
}
For those who wonder what is navigator.sendBeacon you can read here to learn more. Practically I use it because I want the api/logout to be accessed even if the tab closes.
You may start a ajax request by page onload, and get a tracking session id/serial from server.
Later force all of the requests operations to include the tracking session you just gave to the page using the ajax call above.
If user opens up a new tab, the ajax load starts again. and As far as you check the live session tracks in the server with associated user, you may redirect the user to somewhere else or etc.
I don't think you may rely on onbeforeunload, just the same thing you experience.
As others stated, http is stateless, and cookies and requests are only stuffs you can check the state of the user.
At the server, session cookies could be invalidated by session timeout(if we assume user going to brew some coffee, e.g. it closes the page/tab).
And as explained in above solution, if he/she opens a new tab, the new ajax call might block him/her to perform a new login or etc.
I suggest you may find another solution instead of this approach you are trying to get. It's much easier and more senseful to sync the page state with the last opened page. Let the user opens 5 same page, and just sync them all with each other(simplest solution: refresh others when one gets updated)
You may have a javascript function and invoke it on "onunload" of body and in that script invoke backend code to invalidate the user session.
localStorage can be use to keep idle time for the application with multiple tabs are opened.
// Check browser support
if (typeof(Storage) !== "undefined") {
// Store an item to localStorage
localStorage.setItem("timeIdle", "0");
console.log(localStorage.getItem("idleTime"));
// Retrieve the added item
} else {
//display this message if browser does not support localStorage
console.log("Sorry, your browser does not support Web Storage.");
}
function func(){
$(this).keypress(function(e) {
localStorage.setItem("timeIdle", "0");
});
$(this).click(function(e) {
localStorage.setItem("timeIdle", "0");
});
timerIncrement();
}
function timerIncrement() {
var timeIdle = localStorage.getItem("timeIdle");
timeIdle = parseInt(timeIdle) + 1;
if (timeIdle >= 1) {
logoutCall();
window.location = window.location.origin+"/riskoffice-ui/Login";
}
localStorage.setItem("timeIdle", timeIdle.toString());
}
setInterval(func,1800000); //Runs the "func" function every second
I can:
assign a temporary ID to an unlogged user,
collect events
use alias to keep track of the user (all the events appear in the mixpanel people section).
My problem is that if
the user logout, and the cookies gets cleaned out,
when my user come back I assign a new temporary ID to my unlogged user
than it logs in again,
so I use the alias again (with an unknown temp ID and a known user ID) but mixpanel is not able to link that it was the same user again.
These events are lost, they appear nowhere in the people section.
Is it because I explicitly set the distinct_id property of my user (in the mixpanel.track method) ? or it is just not possible to do this operation of tracing unlogged operation and finally realizing that it was a known user ?
If user LogOut there is no way to tie his activity between LogOut and LogIn after cleaning cookies. So this is how Mixpanel's user identification model works together with cookies.
According to Mixpanel documentation - you should use alias() only once in a user lifetime after Signing Up (Registering).
If you use alias() on the last step - Mixpanel will ignore it.
You must use identify() method instead of alias(), but of course Mixpanel will accept only events fired up after indentifying user.
This scenario is described here in Advanced Aliasing: https://mixpanel.com/docs/integration-libraries/using-mixpanel-alias
Their example says about user coming back from Phone insted of PC, but clearing browser cookies means anonymizing (like using another device).
In any general scenario LogOut should not lead to resetting mixpanel's cookies. Can you provide more specific information? Maybe there is a way not to reset them?
For example in my project one device can be used by many users, so this works just fine for me.
I'm a Meteor newbie. In my client.js file I have:
if(Meteor.isClient) {
Template.infooutput.output = function() {
return Session.get("info"); }
I have a template:
<template name="infooutput">
{{output}}
</template>
and then in my main page
<body>
{{>infooutput}}
</body>
Now through console, if I set the Session.set("info", "hello")
I see on the screen, "hello". So that works fine however if I open another browser tab, with the same page open, I don't see the "hello". Is this update functionality only possible with use of a collection? Also, I'm a little confused about the purpose of a Session. Can you tell me why it might be used? Am I able to have current session updates shown in multiple browsers (other users viewing) without saving to my collection db?
If so, how might I do it?
Session data are isolated to the current browser instance (including tabs) - so opening a new tab will give you a clean state. Session variables are designed to be a programmer-controlled means to create reactivity on an individual client. They are one of several reactive data sources which can trigger client UI updates.
Meteor is designed to sync data with the client via collections, however there are other techniques that have been developed by community members. Most notably streams.
It's also worth noting, that the server can publish documents to the client which are not necessarily represented in the database. Please see this answer for more details.
I'm doing a javascript single-page app which allows people to log in, either via twitter or (for some use cases) anonymously.
A very important thing to figure out was how to let them reload the page -- this shouldn't force them to log back in!
I figured this out pretty quickly for the twitter login, and so it uses cookie-stored information to log back in (specifically, the user_id, oauth_token and oauth_token_secret).
However, I can't seem to make this work with the anonymous login facility.
I tried:
auth.login("anonymous", {
user_id: #get("userId"),
firebase_auth_token: #get("firebaseAuthToken")
});
but it doesn't work... I get a new anonymous user ID. I want to keep the same one for the duration of the user's browser session.
And yeah, I tried both user_id and id, firebaseAuthToken and firebase_auth_token.
Thanks!
By default, sessions are created any time you successfully log in a user, and last up until the session expiration time configured under the 'Auth' tab in Forge. This built-in sessioning applies to all Simple Login authentication types, and is automatic as long as local storage and cookies are available.
To resume a session, simply instantiate the FirebaseSimpleLogin object with a Firebase reference and callback. If a local session exists, the callback will be invoked with the same payload you would see if you had just logged the user in for the first time. Invoking the login method will always generate a brand new auth. flow regardless of current user authentication state or session.
Note that in anonymous auth, once a user session expires it cannot be recovered. This may change in the future or some additional functionality may be added to enable it, but it is currently only logged-in to once per user id.