Pass data between refresh/reload (client side, without server side sessions) - javascript

In a singlepage application I'd like to pass sensitive data during a page reload/refresh.
Since the data is sensitive it should not be recovered, for example
when a user leaves the domain and then goes back
when a user closes the user agent and restarts it, restoring the previous session
History
thirdpartypage.com (discard data when moving to here)
mypage.com
thirdpartypage.com (discard data when moving to here)
My approach was store it in the sessionStorage.
// On data generation/update
sessionStorage.setItem("data", "DATA");
// ...
// On load (reload)
var data = sessionStorage.getItem("data")
if (data) {
// Initialize application with data
} else {
// Start without
}
Unfortunately, in the sessionStorage the data persists when moving from my application's domain to a foreign domain (and back or forth to my application's domain).
I also tried storing it in
window.name, but while for Chrome this is acceptable (not persisted across domains), Firefox makes the data accessible at the other domain (IE untested)
a short-lived cookie but I don't find this solution secure

If you have a text input that is populated after the page is loaded, on refreshing the page, the browser will repopulate that field with the previous value. If the user leaves the page and comes back to it(not reload), the field will not be repopulated anymore.
So what you could do is to put the ssensitive information in a hidden text input and fetch it from there, it will be there only if the user has refreshed the page.

There's two distinctively separate issues here to consider:
Sensitive data is left on the computer when a user navigates away from the site without logging out, and then later on somebody else visits the site and stumbles on the previous user's data.
Someone with access to the same computer is actively trying to get their hands on your data, and goes poking around in the browser's sqlite database.
For the first case it would be enough to somehow differentiate between a page reload and a new visitor. Once you know that, you could just wipe sessionStorage for new visitors. document.referrer will tell you if someone is coming in through a link, but it can't tell if somebody typed in the address or if the page was just reloaded. Maybe combined with a short-lived cookie you could come up with a solid strategy.
The second case is more tricky, and I think you'll have to consider if the data in question is that sensitive that someone would go to these lengths. One could also argue that the user should have some responsibility for protecting their data as well. One solution could be to store that data in sessionStorage encrypted, and in window.onbeforeunload store the key in a short lived cookie. If the cookie still exists when the page is loaded you can decrypt the data and resume session, and if not, purge the storage.
I'm not sure if these methods are acceptable to you, but I'm not aware of a better way to achieve this. That's not to say one does not exist. However, if you do choose to go the encryption way, crypto-js is my go-to solution for javascript encryption and hashing.
Here's a pseudocode example:
global var user
when page loads {
encryptionKey = getEncryptionCookie()
if encryptionKey is null {
// No key found, this is a new user
eraseSessionStorage()
user = initNewSession()
} else {
// Cookie found
data = decrypt(getFromStorage('user-data'), encryptionKey)
if data is valid {
user = restoreSession(data)
} else {
// Wrong key, either an anomaly or a hack attempt
eraseSessionStorage()
user = initNewSession()
}
}
user.key = newEncryptionKey()
}
when user does something {
user.data = getNewData()
saveToStorage('user-data', encrypt(user.data, user.key))
}
// ie. window.onbeforeunload in JS
when user leaving {
// the validity has to be long enough to last
// through a refresh, but short enough so no one
// can re-enter the site without the user noticing
setEncryptionCookie(user.key, 10 seconds)
}
This way the data is never saved unencrypted, so even if somebody manages to grab it from the sessionStorage it's useless, provided of course that you generate secure keys. Maybe use the mouse position as a seed for a randomizer function?

Related

Updating LocalStorage with the same data in the same time on multiple tabs causing problems

first of all i'm a beginer front end developer and i'm not a native english speaker so sorry for any mistake i made in my first question :D I'm working on project in Vue that was started by someone else. It uses websocket to display some notifications from server and i spotted a bug associated with this. The notifications are stored in object that pulls data from localStorage using VueUse's useStorage:
const state = reactive({
liveNotifications: useStorage("liveNotifications", []),
notificationsCount: 0,
});
And when data is received from ws it's being added to the beginning of the array like this:
connections.alerts.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data?.status) {
return;
}
state.liveNotifications.unshift(data);
state.notificationsCount += 1;
};
The problem is, when more than 2 tabs are opened and ws send some notifications, the localstorage starts acting weird like its trying to add the same objects over and over and notificationsCount is jumping (for example) from 2 to 3 and vice versa.
Is there any way to e.g. prevent app from updating localstorage multiple times if the data given from ws is the same on all tabs. Or maybe there's another way to make this work properly?
I've tried some solutions from web but to be honest i'm not really sure why is this happening and i didn't know what exactly i was supposed to look for so if someone has better knowledge than me and can help me understand i'm here to learn :)
The problem is: both tabs will read/write to the same "file".
The localStorage read-only property of the window interface allows you to access a Storage object for the Document's origin; the stored data is saved across browser sessions.
MDN - Window.localStorage
Suggestion here is to use sessionStorage instead:
[...] the difference is that while data in localStorage doesn't expire, data in sessionStorage is cleared when the page session ends.
Whenever a document is loaded in a particular tab in the browser, a unique page session gets created and assigned to that particular tab. That page session is valid only for that particular tab.
It sounds like you need a shared worker.
Since you are receiving the same data it is reduntant to keep two connections.
You should handle your websocket connection in a shared worker, then upon receiving the data save it to the localStorage, then post a message to the tabs to update the UI.

how to pop up a Notice Span when user just log in (but not just refresh to the home page)?

I do not know how to detect it is the first time that user login the web.
I thought i should write a pop-up span on the jsp that user firstly saw when he login.but the issue is then he refresh the page,the notic will show again,that is ridiculous.
I need detect if it is first login means to detect if the user JUST LOGIN or NOT REFRESH the page
how and where shall I detect if it is the first time user login ? and then i can make mind if the notice span pop up.
and I think it should use cookies or session,but which one should i use?
Maintain a field in database table that check if it is first login than show a popup and after that change the value of that field so that Popup do not appear next time.
Ex:
if($data['first_login'] == 1)
{
// show popup
}
If you want to show it only to the new user (the time user registers) you can use a table column in database where you can use it to check if the user if logging in for the first time (e.g firtsLogin the column name = 1 ). If he is logging in for the first time you show the pop-up and change the value of the field to 0.
Otherwise if you want to show to users that are logged in to a specific device for the first time you should use cookies.
I suppose that you want to detect the user logging in to your web-site the first time. There are multiple ways that you can do it depending on your desire to spend additional time writing the code, the location of your logging-in logic (client or server side), security that you want to have while proving your users with login functionality. In all cases - you would have to store the data whether the user has logged in for the first time. I think you are seeking a fast solution that will work without a big care for privacy or security as working with client-side cookies isn't the safest way to store data. The alternatives to cookies are web tokens, url query string, server-side sessions and data-base (RDBMS) storage.
Storing and retrieving the data on the client-side using COOKIES. They are the pieces stored in the user's web browser. Cookies were created to help servers remember the data about the user next time he enters the web-site. The most common usages are: to store location (if accepted by user), web-site locale (language in which the user was browsing the site), products added to cart, etc. Following that approach you can create cookie after the user has logged in to your web-site as follows:
This should be run by your JavaScript.
document.cookie = "firstLogin=true";
After having done that, you would have to add JavaScript logic that will hook-up to user's/client's COOKIE data and read up whether he has logged in the first time before.
This would probably look like a simple JavaScript cookie look-up.
var cookieData = document.cookie;
This will return all of your user's cookies that has been previously stored when he visited your web-site. It will return it as a string concatenated with "; ". If we had previously stored only one cookie, we would get firstLogin=true;
In case if you have multiple cookies set before, you would have to parse the cookie string and extract the data either imperatively by plain procedural JavaScript code or by writing the function which will be able to do that repeatedly. Detailed examples of writing such functions could be found here.

reliable way to find site refereer

I am currently working on a task where for example an user visits www.site.com satisfying a particular condition I am supposed to make some visual transformations in the page. But this should only happen for the first time the user is shown the page. Subsequently if the user ignores the call to action and browses the site everything is normal.
To make sure that for a given session this transformation only happens once I am using document.referrer to check if it is
1. an "" string which means user might have entered the www.site.com address directly
!document.referrer.match(/www.site.com/gi); - to make sure that the user is not referred from the internal pages back again to the home page.
This works in most cases except when user gets into the check funnel the url changes to a secure one https:// and when he is referred back to site.com home page the document.referrer returns an empty string which confuses my logic a the user is entering the address in the URL
Is there any other reliable way to solve this problem. Any help is much appreciated and thank you for taking time to read my problem
function transformation(){
// transformation code
}
if(document.cookie.match(/someCookieName/) && document.location.href.match(/transformationPageURL/)){
// call the transformation
transformation();
// set session cookie
document.cookie="someCookieName=true;";
}else{
// not the url to perform transformation or the cookie is already set which means its the same session.
// but still if the user again enters the same home page url the transformation //would not appear due to the cookie being set. But the changes of normal user //visiting the website and again entering the url of home page might be less
}

Detect if site visit is new with js

I would like to check if a user who opens my website is new (type in url OR redirect through google) and then display a message.
But when the user browse through the site (subpages like about and so on) this message is not displayed.
But when the user closes the browser and visits (maybe a few mintues later) the website again, the message should be displayed again.
How can I implement something like this in JavaScript?
You could use cookies, localStorage, sessionStorage or the referrer info. Note that all of them have their own pros and cons and there is no 100% reliable way of detecting new visitors.
Using the firstImpression.js library that Nadav S mentioned is probably the easiest way.
To get the message to show up for users closing and reopening the site:
unset your cookie / localStorage data on unload or
use a referrer info or sessionStorage based solution
See these MDN resources for more:
cookie
localStorage
sessionStorage
referrer
Slightly relevant as well: http://www.cookielaw.org/faq/
From the MDN:
Returns the URI of the page that linked to this page.
string = document.referrer;
The value is an empty string if the user navigated to the page
directly (not through a link, but, for example, via a bookmark). Since
this property returns only a string, it does not give you DOM access
to the referring page.
This means:
if (!document.referrer) {
//Direct access
} else {
var referer = document.referrer;
//Request comes from referer
}
If you want to save this state, you need to take a look at cookies.
Quite easily, you want session storage
var hasVisited = sessionStorage.getItem('washere');
if ( ! hasVisited ) {
// do stuff
alert('Welcome, stranger !');
sessionStorage.setItem('washere', true);
}
You can implement this by using cookies.
When the visitor first come to your page, you check if your cookie exist, if not show the message to them and then create the cookie for future pages.
Using cookies is probably your best bet. They are super simple to use too. Just write
if(document.cookie = "HasVisited=true"){
//whatever you want it to do if they have visited
}
else {
document.cookie = "HasVisited=true"
//that just saves to their browser that they have for future reference
}

ajax and local/session storage pattern

I'm building a web app that uses ajax to communicate with the server. Basically, the user requests a record, it comes back in json, it's added to the DOM and the user makes changes to it. When the user requests the next record, the current record is stringified and sent back to the server and the following record comes back.
All this works really well.... as long as the user keeps requesting records. However, I am wondering how to handle the situation where the user stops his work: how do I get the last record updated?
I thought of adding the working record to the local storage while he's editing it and at each edit, updating the local storage and if he logs on next time and there's still a record in there, ajax it when he logs on. The problem with his approach is that if another user logs on to the same computer, then when that new user logs on, he's updating the data of another user.
I thought of using the window.unload event also; but that doesn't solve the problem of the user closing his browser before the final update.
What are some good ways to handle this issue. Thanks for your suggestions.
I would consider a 'draft-like' feature. Where you could upload changes after a certain amount of time of no input, for instance, after 15 seconds of no input, push those changes.
If your app requires login, you could key the localStorage using their ids like so:
localStorage.getItem( "user13434" )
would retrieve data for user13434
localStorage.getItem( "user12345" )
would retrieve data for user12345
If the information is sensitive but not too sensitive you could add encryption, but it can be decrypted by experienced users which is why it must not be too sensitive.

Categories

Resources