Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I have the variable: var balance = 50;
I am wondering if there is a way to save the balance variable, so that it maintains its amount when a user enters the webpage again.
What should I do? Can I do it with a cookie, do I need to put it in my MSSQL database?
And if I can set it with a cookie how should i do it than?
Or can it be done with a jquery/javascript script, that can save the date.
You can use localStorage
var balance = 50;
localStorage.setItem("balance", balance); // Sets 50 in local storage
localStorage.getItem("balance"); // Returns 50
Limitation - It will not work if user visits page in other browser/device.
You can use localStorage.
var balance = localStorage.getItem('balance');
if (balance === null) {
// Not found, set value from database or wherever you get the value
balance = 50; // Or whatever value
} else {
balance = +balance; // Convert the retrieved value to a number, since localStorage stores everything as string.
}
// After manipulating the balance, etc...
newBalance = balance - 20; // Assuming the user just used up 30 credits
localStorage.setItem('balance', newBalance);
You have to be careful however, as not to depend on this value from a security standpoint, as the user can modify it.
What you're talking about is the concept of persistence. You can achieve this in a number of ways, but they all rely on saving a little piece of data on the clients computer.
1. Use sessions
Most common way to remember a user is to create a session for him on your server. Within this session you can save all kinds of data, for instance a balance. To get this data from your javascript to your session you can send a post request to your server containing the information of the clients balance. The server remembers which user he's handling by the means of a session cookie on the clients computer (contains a unique ID per session).
2. Only use cookies
With javascript you can very easily set cookies doing this: document.cookie = "balance=50". Obviously you'll replace the '50' with whatever value the clients balance actually is. Next time the user visits your page, you can read the cookie again using var cookie = document.cookie. This works even between browser instances.
3. Use a database
If you have the means to identify a user (e.g. he logged in to your website, or by the means of a session) you can just save whatever data you want into a database. Key is to recognize which user you're dealing with.
I like to use sessions when I'm creating a website. I like to keep most of the responsibilities on my server so that I only have to worry about what is displayed on the pages, and not about manipulating data and whatnot. I recommend you using sessions and posting the users balance whenever you want to save it.
Related
I'm not certain it's even possible, but is there a way to keep user information secure across multiple pages while only using javascript?
I have a predefined set of details recovered from three separate API requests, initial call sends user credentials to the login_api via a POST and returns a small set of data (OAuth2 token, user birth name, etc.), the ensuing calls fire, upon success, for 2 lanes of products via GET calls, these requests return a list of products for each lane which is perceived as what this user is licensed to view.
I've not had a great deal of experience in setting up secure user authentication and remembered data across a multi-paged website so I want to ensure I am taking the proper approach.
With the functions below I can create _private variables inside of functions that utilize that data.
All remembered data is applied within the XHR responses to the cookie storage area, it never leaves the scope of the request function.
From that point forward all data is retrieved via cookies, used within a singular function scope, never leaving the scope of the function it is utilized in. Each time the data is required it is re-fetched from the cookies. I'm not certain how secure cookies are, I debated clearing cookies each time the data is recovered and re-applying updated values upon the function's completion, but thought it overkill.
If any piece of relevant cookie data is not present on page load they're redirected to the login page and all relevant cookie data, if present, is removed.
Is there any way to improve retaining an OAuth2 token and handful of user details across multiple pages without leaking user information with only javascript?
NOTE
This is within a rather old internal website and in keeping things familiar for the team we're using ES5 and below, it's moving away from internal use only.
var config = Object.create(null);
config.expire_item = 30; // minutes
function dataref() {
// setup objects to store details in
var output;
output = Object.create(null);
output.access = Object.create(null);
output.licensed = Object.create(null);
output.token = "_token";
// apply predefined names as object values
// cookies in this namespace holds user name
output.fname = "_fname";
// cookies in this namespace store true/false flags
output.has_access.ces = "ces_license";
output.has_access.ezg = "ezg_license";
// cookies in this namespace hold pipe & comma delimited product lists
output.licensed_for.ces = 'ces_products';
output.licensed_for.ezg = 'ezg_products';
// ...etc.
return function () {
// return object with predefined names for cookies
return output;
}();
}
function apply_userdata(fn) {
// get predefined cookie names
var _data = dataref();
return function () {
// apply function to all namespaces
fn(_data.token);
fn(_data.fname);
fn(_data.access.ces);
fn(_data.access.ezg);
fn(_data.licensed.ces);
fn(_data.licensed.ezg);
}();
}
function resetCookieExpire(name) {
// updates cookie expiration period.
return setCookie(name, getCookie(name), option.expire_item);
}
function getUserSensativeData(name) {
// retrieve cookie value
return getCookie(name)
}
function deleteUserSensativeData(name) {
// remove cookie name/value
return deleteCookie(name);
}
I should preface this with "I'm no auth expert either", however I have worked with several different kinds of user auth in the past on multiple projects. There's a little bit of missing information that seems implied by what you're saying, but it appears you are either using oauth2 implicit flow or oauth2 authorization code flow. in either circumstance, in order to persist across separate page loads, you would have to use either cookies or local storage as you currently are, unless it's a single page application, in which case it sounds like it's not.
Based on how you've described this project it sounds like you're trying to sunset it, that being said, if you really feel bad about storing these client side credentials you could switch to an OIDC style flow that uses secure=true;httpOnly=true cookies that automatically get sent with each request. That sounds like it's not an option for you.
Oauth2 is considered secure, and storing a client side credential for repeated use is not "breaking" any rules. The reason storing a client side credential can be considered vulnerable is because of XSS or CSRF attacks
Having a Content Security Policy goes a long way too.
There are additional precautions you can take, such as having a short expire time (1 hour is pretty common) or even having the ability to manually expire access_tokens in an emergency. Hope this helps.
Can anyone tell me how to fix this one line and save this one variable so I can get on with my day?
I'm a total noob to browser extensions. My extension is intended to make changes to any webpage a user visits, and determines what changes to make by AJAX querying a database - that much works fine. To make my extension valuable for multiple users though, each user needs an ID number that persists across all domains.
My system works like this: on log-in at the extension's home site, the user gets a cookie with an encrypted ID number. I need to get that number from the cookie and save it in local storage, but I can't figure out how to save the ID number. The critical code is this:
//If we've just logged in we get our ID number from the cookie:
if(visitedURL.indexOf("log-in site name here") > -1){
userId = getCookie("the cookie");
//Then we make a key/value pair to hold our ID number
userStorage = {
key : userid
}
//And then, we attempt to save it. Uncommenting the following causes my extension to break.
setting = browser.storage.local.set({
userStorage;
});
}
I used this as my guide:
https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/storage/StorageArea/set
I save some data belonging to the authenticated user in the session and I want that when the user object is updated in the database users collection, to set somehow the updated data in the session of the user. This may not happen in the request - response workflow. Maybe it's a random script updating user data in the database.
How to update a specific session data with the new data that is set in the database?
Currently to set the data I do:
req.session.userId = 7;
req.session.foo = 42;
Let's assume that I want to turn 42 into 43 for the session data which has userId === 7. How to do that?
I'm using the express-session module.
I know that one solution is to reload from the database the user on each request, but that would not be performant, since it would create queries that can be avoided.
What's the best way to update the session data of the user, knowing a field that was set in the session (such as the userId)?
I use the connect-mongo store.
Using sails.js, is there a way to run a function when a user session expires or is finished? Some configuration to do in config/session.js?
I know exists session.destroy, which you can set a function to execute when the session is destroyed, but I need it to be a global unique function for the application.
The idea would be writing in db table the state of a user as offline, when it's session ends.
Thanks.
If you're asking if there is a way to see if a user's session has expired -
Yes! It depends on how you're storing the server-side component of the session. Remember, traditional sessions require 2 pieces to work correctly - something on the client side (a cookie for example) and something on the server side to remember the user. In Sails the server-side piece is stored in the data store specified in the adapter portion of the Session Config File. You can query this data-store (even if it's the default Memory Store) and look for all users that have expired sessions.
Going deeper...
If you're asking if there is a specific method that gets called when a user session expires, then no, that's not the way sessions work. Sessions are a "hack" to make HTTP stateful. They aren't an active/live thing in the way that if they die we are notified. A session is just a record (likely a database) with a long code and a date. When the user visits your site, they give you a code from their cookie and you verify against the record in your session database. If the record matches and hasn't expired, HURRAY! you know who they are and they continue with their request. If the record doesn't match or has expired, BOO!, prompt them to log in again.
Really jumping to conclusions now...
I presume from the last sentence that you're looking to try to monitor whether someone is logged in to track "active" users. I would suggest that sessions are a poor metric of that. With sessions I can log in to your site and then leave. Depending on the length of your session expiration (24 hours or 30 days are typical values) I would be shown as logged in for that entire time. Is that a really helpful metric? I'm not using using your site but you're showing me as "logged in". Furthermore I could come back on another device (phone or another browser) and I would be forced to log back in. Now I have 2 or more sessions. Which one is correct?
If you're trying to gauge active usage I would either use Websockets (they would tell you exactly when someone is connected/disconnected to one of your pages - read more here) or just have a "heartbeat" - Each time a user visits one of your pages that visit is recorded as last seen at. This gives you a rough gauge as to who is actively on the site and who hasn't done anything in, say, over an hour.
You can do this by adding policy to all route
for example add sessionAuth.js to policy folder :
module.exports = function(req, res, next) {
// If you are not using passport then set your own logic
if (req.session.authenticated) {
return next();
}
// if you are using passport then
if(req.isAuthenticated()) {
return next();
}
//make your logic if session ends here
//** do some thing /
};
add this lines to config/policies.js :
module.exports.policies = {
'*': 'sessionAuth'
}
I just want everyone to know that I am in no way a professional web developer nor a security expert. Well, I'm not a beginner either. You can say that I am an amateur individual finding interest in web development.
And so, I'm developing a simple, small, and rather, a personal web app (though I'm thinking of sharing it to some friends and any individual who might find it interesting) that audits/logs every expense you take so you can keep track of the money you spend down to the last bit. Although my app is as simple as that (for now).
Since I'm taking my app to be shared to some friends and individuals as a factor, I already implemented a login to my application. Although it only needs the user key, which acts as the username and password at the same time.
I've used jQuery AJAX/PHP for the login authentication, as simple as getting the text entered by such user in the textbox, passing it to jQuery then passing it to the PHP on the server to verify if such user exists. And if yes, the user will be redirected to the main interface where his/her weekly expense will be logged.
Much for that, my main problem and interest is within the security, I've formulated a simple and a rather weak security logic where a user can't get to the main interface without having to login successfully first. The flow is like this.
when a user tries to go the main interface (dashboard.php) without successfully logging in on the login page (index.php), he will then be prompted something like "you are not able to view this page as you are not logged in." and then s/he will be redirected back to the login page (index.php)
How I've done this is rather simple:
Once a user key has been verified and the user is logged in successfully, cookies will then be created (and here is where my dilemma begins). the app will create 2 cookies, 1 is 'user_key' where the user key will be stored; and 2 is 'access_auth' where the main interface access is defined, true if logged in successfully and false if wrong or invalid user key.
Of course I'm trying to make things a little secure, I've encrypted both the cookie name and value with an openssl_encrypt function with 'AES-128-CBC' with PHP here, each and every user key has it's own unique iv_key to be used with the encryption/decryption of the cookie and it's values. I've encrypted the cookie so it wouldn't be naked and easily altered, since they won't know which is which. Of course, the encrypted text will vary for every user key since they have unique iv_keys although they have same 'key' values hard-coded in the PHP file.
pretty crazy right ?. yea i know, just let me be for that. and as how the main interface (dashboard.php) knows if a user has been logged in or not and to redirect them back to the login page (index.php) is purely easy. 'that' iv_key is stored together with the user_key row in the database.
I've attached a JavaScript in the main interface (dashboard.php) which will check if the cookie is equal to 2, if it is less than or greater than that, all those cookies will be deleted and then the user will redirected to the login page (index.php).
var x = [];
var y = 0;
//Count Cookie
$.each($.cookie(), function(z){
x[y] = z;
y++;
});
//Check if Cookie is complete
if (x.length != 2) {
//If incomplete Cookie - delete remaining cookie, prompt access denied, and redirect to login page
for (var i = 0; i < x.length; i++) {
$.removeCookie(x[i], { path: '/' });
};
alert("You are not allowed to enter this page as you are not yet logged in !.");
window.location.href = "index.php";
} else {
//If complete Cookie - authenticate cookie if existing in database
}
As you can see, the code is rather incomplete, what I want to do next after verifying that the count of the cookies stored is 2 is to dig in that cookie, decrypt it and ensure that the values are correct using the 'iv_key', the iv_key will then be used to decrypt a cookie that contains the user_key and check if it is existing in the database, at the same time the cookie that contains access_auth will also be decrypted and alter it's value depending on the user_key cookie's verification (returns true if user_key is found in database, otherwise false). Then after checking everything is legitimate, the cookies will then be re-encrypted using the same iv_key stored somewhere I don't know yet.
My question is and was, 'where is a safe location to store the encryption/decryption key?' and that is the 'iv_key'. I've read some threads and things about Session Variables, Local Storage, and Cookie. And I've put this things into consideration.
SESSION - I can use session storage of PHP to store the key in something like $_SESSION['user_key'] then access it later when needed be. But I've read an opinion saying that it is not recommended to store sensitive information including keys, passwords, or anything in session variable since they are stored somewhere on the server's public directory. And another thing is the session variable's lifespan, it lasts for around 30 minutes or so. I need to keep the key for as long as the user is logged in. The nice thing I find here is that, it'll be a little bit hard to alter the value and I don't need to encrypt it (the iv_key) here since it is server sided, and hidden to the naked eye, well not unless when being hacked of course. What I mean is, they don't appear on the debugging tools just like how localStorage and Cookies are visible there.
LOCAL STORAGE - this eliminates my problem of lifespan, since it will be stored in the localStorage vault of the browser not until I close the browser. But the problem here is that the values can easily be changed via console box of the debugger tool, I can eliminate this problem by encrypting the 'iv_key', but what's the point of encrypting the encryption/decryption key? Should I encrypt it using itself as the 'iv_key' too? Or I can use base64_encode?, which eliminates the security of needing a key, and can be decrypted so easily with no hassle.
COOKIE - this one adopts two problems, one from session variable and one from localstorage. From session variable, I mean is the lifespan. As far as I've read, cookies last for about 1 hour or so, but still depends if an expiry has been declared when setting the cookie. The other is from localStorage, since it can easily be altered via console box of the debugger tools too. Although I've already encrypted 2 Cookies beforehand, but what's the point of storing the encryption key together with the values you encrypted?, should I go on with this and encrypt the 'iv_key' by itself, just like what I might do with localStorage?.
I'm lost as to where I should save this sensitive 'encryption_key' as it is crucial in encrypting and decrypting the cookies and other information my app needs.
Why am I so devastated with such security, despite having a simple worthless app?.
Well, because I know and I believe that I can use this as a two-step further knowledge which I can used with my future projects. I maybe doing web development for fun right now. But I'm taking it to consideration as my profession. And so, I want my apps to be secure in any means.