Remove session variable when user leaves page - ajax

I have a page that sets a session variable to hold a list of lookups from the database for the page when the page is loaded.
The page also will need to access that list of lookups when Ajax calls are made from the browser.
I'd like to not load the list of lookups from the database for each Ajax call, but I would like to remove the list of lookups from the session if the user leaves the page. Is there a best practice or recommended strategy for doing this?

You can clear the session variable with javascript using something like this
window.onbeforeunload = cleanup;
function cleanup()
{
// Clear session variable here
}
However, this isn't foolproof since the user could always disable javascript, etc. Usually this won't be an issue since the session variable will have a timeout anyway. If you are really concerned, you should remove any current sessions on page load.
Another option, depending on your situation, is to use the Caching.Cache class to hold the values. When you insert the values into the cache, you can set them to expire after a TimeSpan, and just set it for pretty short, like 5 minutes or so.
Note that while sessions are per user, their is only one cache per server instance.

Related

Hidden authentication in some websites

I find that some websites have sort of authentication even though no user is logged in. Taking plunker for example, even a non-logged in user can freeze a snippet such that other users cannot modify; whereas the user himself could always modify the snippet even though he opens the link in another browser tab.
My current solution is adding a type field (ie, anonym and normal) in the user model. Then, each time there is no normal user logged in, I systematically generate a unique random ID, register and login as an anonym user. It works, but the shortcoming is there are lots of anonym users in my database.
Does anyone have a better solution? Is there any "standard" way to realize this kind of hidden authentication?
I think method you are looking for is called session id. When you save as anonymous user web app creates a session with a session id which is used to identify the user by link. For example on plnkr it'll be something like https://plnkr.co/edit/session_id?p=catalogue where session_id is some sort of hash.
To freeze the snippet the session id is written into cookies with the flag, saying, for example, that the state is frozen. If you freeze it in Chrome and open in a Chrome's private window or in Firefox on the same computer, you wouldn't be able to unfreeze it. It'll behave the same way as for other users which have no cookies. In fact using session hash for cookies, rather than any user identification is better for security reasons.
Now this approach in a sense isn't any better, than creating anonymous users - you still have to save session records into the database to be able to open session context by link. In fact, it might happen to be simpler in your case to do exactly what you did if user is assumed to be present in lots of use cases and places in the code.
In many cases, however, separation of session from user makes lots of sense as it simplifies keeping session state after login or registration. Say some web stores would empty your basket after you register, causing quite a bit of frustration, especially if you put several small items into it which you now have to find again and put back. Those don't have sessions or don't use them correctly on registration or login.
Otherwise, as I wrote it's pretty much the same and you have to deal with many anonymous sessions which pollute the database unless you have some sort of wise retention policy, depending on you use case. Say, for example, a web site similar to plnkr.co which is used to share code snippets, and post them on sites such as stackoverflow should better keep those sessions while there are users accessing those say at least once a year. So sessions should have access date and policy would be that it's older than 1 year.
Hope it helps.
I have done similar using Local Storage. It allows you to store data on the browser. A user can then open tabs, close browser completely and reopen etc and the data is still there. It would then appear to be saved for them but actually it's just stored on their browser.
This wouldn't allow others to see what they have done though, so not sure if this is quite what you're after.
I wrapped them in functions in case I chose to change them out later, something like this
StoreLocalVariable: function (key, value) {
localStorage.setItem(key, value);
},
GetLocalVariable: function (key) {
return localStorage.getItem(key);
},
Some info including compatibility
https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API

gorilla/sessions persistent between server restarts?

I have a general question about sessions. I am not very seasoned when it comes to this subject. I've tried with:
NewRediStore (gopkg.in/boj/redistore.v1)
NewCookieStore
NewFileSystemStore
I was under the impression that sessions could last between server restarts, hence the need for a 'store'. While my golang backend is running, I am able to set new sessions and retrieve them for multiple users/browsers. No problems there.
When I restart my server, I notice that all session access results in session.IsNew == true.
In Redis, I can see all the session keys after the restart, and even verified that .Getting the session results in the right ID retrieved, but IsNew is still set.
I guess intuitively, this makes sense because there must be some map in memory that leads to the setting of IsNew but I would think that if there was any hit for the cookie key in the store, IsNew should not be set. Am I going crazy? Is there something easy that I am doing wrong? Is this a fundamental misunderstanding of how to use sessions?
Please let me know if I need to include code or additional details.
I would have had the same assumptions you did, and browsing the source, it looks like it should work as you described. You might try debugging and stepping through it, particularly the New method for the store you're using (e.g. FilesystemStore.New or RediStore.New). If that method successfully reads the cookie and finds the session in the store, it should set IsNew = false, according to the source.
Also note that just checking the session ID is not a good way of validating this behavior. If you look at the source, it decodes the session ID from the cookie, then tries to look that up in the backing store. If the lookup fails, then the session ID will match, but IsNew will be true and there won't be any values in the session. Make sure you're setting some value in the session and check for that instead of the session ID. The behavior is different for the CookieStore since it stores the session data in the cookie itself.

dynamic session timeout

Can I change the session timeout dynamically? The timeout must be set according to the user role. I tried to use configure::write to change the timeout dynamically but it doesn't work. it seems that for the new session timeout to take efect, you have to reset the session, but resetting the session will loss the login info.
I think using something like the following after you check role membership will get you what you want.
HttpContext.Current.Session.Timeout = 1200;
I think you are right when saying you can't change the session timeout after it has been created, maybe you could look at regenerating one with a new timeout.
But maybe a more easy solution would be to use javascript, you could set a timeout value and when it runs out send an ajax request logging the user out.
This obviously won't work if a user disables javascript but it depends on how secure you want this to be.
Rather than changing the session timeout, have you considered using a variable in the session to store the date/time of the last pageload, so that you can check it on the next pageload?
You could add some code to the beforeFilter() method in AppController to calculate the amount of time elapsed between the last pageload (stored in the session) and now, and if this is greater than the session length for your specified user role, destroy the session. If not, store the current date/time in the session, so that it can be used next time.

Storing User Doctrine object in symfony 1.4

Throughout the application I need to access User object (Doctrine) several times per execution (I mean each time page is displayed) so on some, and instead of retrieving it from database every time, I thought it would be better to store it once and then reuse it.
Can I store it in sfContext?
Symfony discourages saving objects into the session, see here for example: http://www.symfony-project.org/gentle-introduction/1_4/en/06-Inside-the-Controller-Layer#chapter_06_sub_accessing_the_user_session
... But you can save user_ids and other bits that save on queries. It really depends on whether the things you need to do on all those pages require the entire user object. If yes, $this->getUser()->getGuardUser() is what you'll end up using everywhere.
If you're referring to the currently logged in user object, it should already automatically be loaded for you. At the point of authentication, the system loads the user record and it will remain there in the session.
In actions, you can retrieve the user object with:
$this->getUser()
In a view, it's already loaded into the variable:
$sf_user

Sessions in Codeigniter

I am using sessions to store data from my multi step form so that when the user completes all three sections of the form then the information is inserted in to the database. I have built the form so that the user can go back to any stage and modify the information they have submitted, the thing is though, the values that repopulate the form are stored in sessions so if the user leaves the form page and goes elsewhere in the website and then returns to the form the information is still in the form…is there a better way to do this? I want the data destroyed if they leave the form…
Thanks
Assuming your form exists only in one controller and isn't spread across multiple ones, you could simply unset all session values in the __construct of every other controller. (You could extend the base controller if you have lots to save the hassle of adding this functionality to many.
That way if the user visits another section, the values will be lost, but providing they remain within the "form" they can remain intact.
You could with JavaScript and the unload event, but it'll prove tricky since unload may fire with each "section" of the form.

Resources