Storing user variables in database vs session in asp.net - asp.net

I'm working with an asp.net application that stores most data in a database and not session. I'm wondering of the pros and cons of each and which is the better way to go. For example, you have a pretty busy site and instead of storing user specific variables in session, there is a DB table called user data and it can store all user specific data that can be accessed from any page by querying the database. Which is the better way to go, session or database?

Session (but it depends a lot of the session configuration) :
No database access, or less.
Temporary storage : you may lose the information, at least when the session ends.
Maybe some security issue, depending on where you store the session information
Not shared : you may have issues if you're using a server farm, one server may not have access to the other server session.
May not work if the client disabled the cookies.
Database :
Database traffic for each postback if you need the information on each page.
Permanent storage.
No information stored with the client (cookies...).
Shared : data accessible from any server on a web farm.
Please note that you can store Session information in database. That's why I use the word "may" in the Session part.
See here some session configuration and possibilities

Anything stored in session state will vanish when the AppDomain is reset.
You could avoid that by using an out-of-proc session state handler, but that's no better than a database.

Interesting question. If it's data that's not important across sessions (say, last page viewed) -> session. If it's data that should be persistent (say, password) -> database. The interesting case and the one you probably refer to: Data that should be persistent but is also used often (say, the username). From these, I tend to copy those values from the DB into the session that allow me to work without database access in pages with trivial tasks.

In many cases, I use Session to store temporary data about the... well... "session". In ASP.NET, session is configurable. You can use in-proc (default) which uses the server's memory. You can also configure session to use a database or a session management tool (in case server memory is a problem or you move to a cluster/farm environment).
Session is meant to be temporary. This is great when you are truly storing data about the user who is using your application at that moment. When the user leaves the app and his/her session expires, the memory is freed up. You don't have to manually clear anything out.
Session uses the server's memory. As long as you have enough memory and you're not on a server cluster, this works great. Memory is fast, so getting and setting data in session is very fast and uses zero network bandwidth.
Have said all that, in a few of my apps, I have session configured to use SQL. It's basically the same as using the database directly, but I don't have to deal with DAL... just let the framework work for you.

Related

What are the pros and cons of using session variables to manage a users session data?

Using ASP.NET I have always used session variables to maintain a users session data.
Typically: (Coded as simple bools/ints with around 12 total variables)
User information.
Page security permissions.
I have read increasing information regarding the negative effects of using session variables.
I am aware that session variables are stored in memory and the negative effects that using too many can have; this is not the desired scope of this question.
What I would like to know:
Using current development languages and features:
Do session variables pose a security risk?
(By security risk I mean is it possible to read / alter variables)
Is there better performance using querystrings, viewstate, caching, or making database request on every page load?
What is "considered" good practice for handling a users session data. (All topics relating to this subject are now very old and perhaps no longer relevant)?
A performance is always something subjective and may vary depending on different things. In your case you're trying to compare incomparable because
querystrings cannot be used to share sensitive user information or page security, because everyone can modify urls directly in the browser
viewstate is set and maintained on the page level. It cannot be carried across different page requests, only on postbacks of the current page.
caching is done on the application level, and all users can access it. It might work in case of page security permissions but not applicable to store individual user information.
Making database requests is the only comparable option and yes, it's slower than a session. This is where you can try to play with viewstate and caching and try improve performance and reduce a database workload.
Sessions are stored in a memory on the server but depend on cookies and in theory, it's possible to hijack the session by stealing the asp.net session cookie.
SessionID values are sent in clear text. A malicious user could get
access to the session of another user by obtaining the SessionID value
and including it in requests to the server. If you are storing
sensitive information in session state, it is recommended that you use
SSL to encrypt any communication between the browser and server that
includes the SessionID value.
Quote: http://msdn.microsoft.com/en-us/library/ms178581.aspx
Bottom line: using sessions is secure but to make it more secure use HTTPS
ASP.NET provides out of the box functionality for user authentication, role based authorization and user profiles which might make sense to use. Read more about profiles: How to use Profile in ASP.NET? and Regarding Profile and session in asp.net There is a lot of other topics and answers here on this site regarding authentication and authorization.
Do session variables pose a security risk? (By security risk I mean is it possible to read / alter variables)
Although, as smirnov quoted, a malicious user might get accrss to another user's session by hijacking the session itself, the session variables themselves are stored at server-side, and cannot be accessed directly.
Is there better performance using querystrings, viewstate, caching, or
making database request on every page load?
As smirnov wrote, the comparison isn't exactly valid. However, consider:
querystrings and viewstate are stored in the http request, therefore are both less secure and consume no memory. However, they will take some minor processing power to parse.
Caching (in the web-server RAM) the results of previous database request will lighten the load on the database and the network connections between your web-server and the DB server, and will also retrieve the data faster. However, they will obviously use more RAM on the web-server itself.
What is "considered" good practice for handling a users session data.
(All topics relating to this subject are now very old and perhaps no
longer relevant)?
Since the principles haven't changed much, the existing sources, IMHO should still be relevant.
Note: If you're using multiple servers, you'll need to synchronize the session data across them, by using a state-server, for example, or use "sticky sessions", in which each session is always served by the same server.
In my opinion you should avoid sessions as much as possible. Here are my reasons in no particular order.
Sessions doesn't scale automatically when you add more nodes (Sure you can use a dedicated session-server but that comes with some overhead)
When you have enabled sessions each user can only make a single request at the same time. Asp.net implements per user locking if the session is enabled to avoid any race conditions. This is mostly a problem in if you use a lot of ajax.
If you have to restart the webserver the user lose their session. This is really the main point for me. It really sucks to have a system where people risk to get kicked out, get a corrupted session or simply lose progress because you need to deploy a bugfix. Avoiding session as much as possible gives you much more freedom and a better experience for your user.
It's up to you but I always try to either store the data in a persistent store or use something that actually exist in the web (cookies, querystring, writing state to a hidden field etc etc). I bet there are situations where I would use sessions but my default choice is to avoid them.
These days there are more options:
Local Storage / Session Storage / Page Javascript Variable - are good for client-side storage situations. see https://www.w3schools.com/html/html5_webstorage.asp. But they wouldn't be suitable for most trust situations, not without server-side signing. A javascript variable will be lost upon page restart, but persist in browser Session Storage if it was written there. If that browser tab is closed, the Session Storage is lost, but persist in the Local Storage if it was written there.
JSON Web Tokens (JWT) - are the emerging new standard for replacing Sessions. This is a standard for authentication, roles, data, and claims, which is signed by the server, and can also be encrypted to the client can't read any of the details. This is usually stored in Local Storage by the client, and only really works for Single Page Applications which can write to the Bearer header. Don't use this for MVC (MVC.Controller) with server-side generation of HTML. JWTs can be a pain to set up and customise - the API for OWIN is terribly sparse. JWTs can get big too, which means you're always "uploading" the JWT data upon each Request to the web-server. But JWTs enable your security to be handled by one server (even an externally trusted server).
ASP.Net Server-Side Sessions - Can be in-memory in-proc, in-memory external-proc, and database.
Answering your specific questions:
Security risk - Not really. The session uses a key that's long enough that it can't be guessed. It's typical to use HTTPS these days, so that value is securely transmitted. The variables are stored only on the server, with a set per user. If a user's device is compromised, it's possible to steal the session key, but if their device is compromised, there are bigger problems to deal with.
Performance is not better or worse for "query strings", "view state", or "caching" compared to In-Proc (Memory) sessions. They're all in the realms of speed of memory (RAM) - nanoseconds. Database (disk stored) is certainly slower, because the medium access time is slower - milliseconds
Sessions are good practice. Some would recommend having a dedicated class for reading and storing each variable (using Properties), so you don't get the session variable names (strings) confused.
I am a fan of a possible hybrid approach to Sessions. see How can I store Session information in a hybrid (Database + Memory) way?

which will give better performance while creating a website a session,cache,or cookie?

I am creating a website,for that I need some kind of storage medium so which one can I use and which one will give better performance to the website.
session
cache
cookie
please give your suggestions.
It all depends on the scenario and their usage.
Basically Caching is used to boost performance and Session is used to share data between multiple pages. Excess use of session bogs down the performance. Cookies are stored on client side and can be used to keep less confidential data on Client browser.
So you have to use all of them wisely to deliver performance
Session is used to store per-user information for the current Web session on the server.
Cookie is used to store per-user information for the current Web session or persistent information on the client, so client has control over the contents of a cookie.
Cache is shared between users in a single application. Its primary purpose is to cache data from a data store and should not be used as a primary storage. It supports automatic invalidation features.
If your application is used by a number of unauthenticated users, then it would be better to store the data in a cookie.If it requires authentication, you can store the data in the DB manually.
On whole this it depends on your need.
session is a way to store variables stored in a session object so that it is accessible to all web pages hosted on the server for a user.
Cookies stored on client machine so not much safe to go for it unless variable are not so restricted.
Cache helps your browser go faster.Hence Caching is used to build high performance web applications.

Store session info in ASP.Net Cookie or Session State?

I need to store some session related data for a user. This data does not need to be encrypted but I want to ensure the user cannot modify it. I think my options are to store it into a hidden field, store it into a cookie, or store it in ASP.Net session state. I need the solution to be server farm safe.
If its stored in a cookie or hidden field then I need a way to ensure a user can't modify it.
What do you think is the best approach for this sort of data?
First question I ask myself about session data: I really need them?
Remember that web is stateless so maybe you can re-engineering your application to not use session state.
Sessions requires a lot of management and server resources.
Meanwhile you have two solutions:
because you are in a farm put your session on SQL Server configuring session state in web.config (it requires resources and it's a bit slower but is the safest way to store session data to ensure the user cannot modify it)
add an encryption/decryption mechanism to your cookie with a private server key
A user is always able to modify cookies, because it is client-side storage. You need to store the data server-side.
ASP.NET Session State is an acceptable solution for your problem, although there are some caveats regarding server farms. This MSDN article explains how to make Session State work for your server farm environment. Be.St.'s answer touches on the suggested out-of-process approach.
A third alternative is to create a database driven session storage that does not necessarily depend on Session state. I find Session State to be a bit of a hassle with different deployment environments (e.g. server farms), so I will sometimes use this approach. You can then access this data by attaching a session key to the querystring or storing the session key in the cookie (still potentially modifiable by the user, but less likely to be a target for such action).
Personally, I reckon it's better to store the information in the cache, although you could perfectly well store it in the session or encrypt it and store it in a cookie and it's just a matter of personal preference
The reason I prefer the cache is that it is not vulnerable to Session Hijacking, so there is no possible way the user can modify it as it's stored on the server (same as session in that respect).
I asked a question about using a custom principal and I included quite a bit of code in there that might help you.
Code to store extra user information in cache: Is this Custom Principal in Base Controller ASP.NET MVC 3 terribly inefficient?
EDIT: And the reason I prefer to store this information somewhere close at hand is that I don't want to kep nipping off to the database all the time as it is very inefficient to do so.
If you need to use a farm and want to share session state among the nodes without going back to the database all the time you could use the AppFabric Session Provider. There is a bit of a learning curve setting it up but it does the job and is fast (don't run it on the same box as your application though).

what is the efficient way to store session variable

My asp.net application is deployed on a load balance system. And I just want to keep a user's role (a string) in a whole session. I was told that session info in asp.net is stored in the database so I don't want to the asp.net engine to access DB ecah time a user switch between pages. neither do I want to get the role from my own DB each time when I need check user's role. I know one way is to store the role info in a hiden field.
what is the efficient way to store a constant session value?
session has three modes. The mode setting supports three options: inproc, sqlserver, and stateserver. you need load balance, the inproc is out automatically. you can configure to use either sqlserver or stateserver.
If you want to avoid DB accesses, you might use cookies to store the user's role instead of session state. You can encrypt / encode the cookie if you need to for security reasons (perhaps using the session ID as part of the key). Cookies work fine in a load-balanced scenario, since they are sent by the browser to the server with every request. Just be sure to set the path attribute on the cookie (and possibly HttpOnly), to limit the URLs that the browser attaches it to.
Note that if you're using the built-in ASP.NET Membership providers, role membership and related details are handled for you automatically by the providers.
You could also use a cookie.
Session data is stored by default in memory, so i guess you have it configured to be stored in a database in order to be available on all servers in the farm.
If you can store it in memory, you could use this approach to deal with the load balancing:
if (Session["Role"] == null)
Session["Role"] = GetUserRole();
This will result in trips to the database only once per server.
More details about Session state here.
If "role" has something to do with permissions it would not be a good idea to store it in a hidden field or an other means that would enable it to be edited from the client side such as in viewstate with talking asp.net.
I am a big hater on session, especially if you are using it to hopefully improve performance. What you probably really want is caching and there a number of great solutions you can look into. Right away you can take advantage of the Cache data dictionary that is built into asp.net and is exposed as a member on the page class. The cache will essentially serialize anything you put in it and store it in memory. Using the cache object will work best with a single server setup. Since you are using load balanacing you will probably want to take advantage of a distribute cache system like Memcached or AppFabric Caching (Previously Codename Velocity). Memcahed is used by a lot of big sites such a Twitter where as AppFabric is a new Microsoft product that is just becoming available but should have good support and integration with other Microsoft technologies such as Asp.Net.
With distributed caching you avoid going back to the database and you essentially trade this off for a trip to your cache. The reason why this is more efficient for starters is that the cache only has to worry about efficiently storing items which have been recently accessed where as the database must store everything.
Also I want to point out that you may choose to avoid the distribute caching route if you are using server affinity with your load balancer. Technically you could use it without server affinity as well but you will have a lot more cache misses.

Cache VS Session VS cookies?

What are the do's and don'ts about Cache VS Session VS Cookies?
For example:
I'm using Session variables a lot and sometimes have problems in a booking-application when users start to order products and then go to lunch and come back some hours later and continue the booking. I store the booking in the session until the user confirms or aborts the booking so I don't need to talk to the database and handle halfway bookings in the database when users just click the X in the browser and never comes back.
Should I instead use cache or cookies or some combination for this?
(Also when there is some error in the app, the session-object resets itself and I get more problems because of that)
I'm mostly doing desktop-programming and feel I lack lots of knowledge here so anyone who can expand on where to use Cache, Session, Cookies (or db) would be appreciated
Edit: From the answers it seems that a combination of DB and cookies is what I want.
I have to store the booking in the database connected to a session-id
Store the session-id in a cookie (encrypted).
Every page load checking the cookie and fetch the booking from the database
I have a clean-up procedure that runs once a week that clears unfinished bookings.
I can't store the booking as a cookie because then the user can change prices and other sensitive data and I had to validate everything (can't trust the data).
Have I got it right?
And thanks for great explanations to all of you!
State management is a critical thing to master when coming to Web world from a desktop application perspective.
Session is used to store per-user information for the current Web session on the server. It supports using a database server as the back-end store.
Cookie should be used to store per-user information for the current Web session or persistent information on the client, therefore client has control over the contents of a cookie.
Cache object is shared between users in a single application. Its primary purpose is to cache data from a data store and should not be used as a primary storage. It supports automatic invalidation features.
Application object is shared between users to store application-wide state and should be used accordingly.
If your application is used by a number of unauthenticated users, I suggest you store the data in a cookie. If it requires authentication, you can either store the data in the DB manually or use ASP.NET profile management features.
Web is by nature disconnected model and none of the options mentioned (Session, Application, Cache, ...) are reliable enough. Session will timeout, worker process recycles, etc.
If you really need to store the users progress, reliably and through extended periods, the database is your only solution. If you have users profile (if the user must log in), then it's straightforward. If not, generate a unique Id, store it in the cookie (or URL) and track the user based on that identification.
Just make sure the Id is encrypted and then base64 encoded string and not just a numeric value.
EDIT:
After your additional explanation in the original question and comment from Mehrdad Afshari, good solution for you would be to use Session but set the storage to Sql Server instead of InProc.
Here's more details and instructions how to set it up: http://msdn.microsoft.com/en-us/library/ms178586.aspx
Have in mind that you will STILL have the session timeouts, but they will survive application pool recycles, even server restarts.
If you truly need a permanent storage, custom solution with the database, as I originally outlined is the only solution.
Session is stored on the server will time out by default in 20 minutes (This is adjustable). I would store this in a cookie, or in viewstate(if available) to prevent the timeout.
If your state is stored InProc(the default setup), then having more than one server in a farm is going to cause you issues also unless you have implemented some sort of "sticky session" that will keep the user on the same server in the farm for subsequent calls.
I try to avoid session when possible(puts extra load and memory usage on the server), and keep viewstate turned off when possible to keep the page size low. Cookies are often the most lightweight option, but your users might have this turned off and you will need a fallback mode that still allows them to use the site.
Edit (adding clarification based on response from asker):
Viewstate is stored in a hidden field, and is a serialized representation of all objects in Viewstate storage. Viewstate is automatically used to store the page's state, but you can explicitly add and retrieve your own objects to and from Viewstate programatically if you choose to.
So yes, datasets can be stored in Viewstate.
First thing you must know! cookies are used by session! The server knows who is your user thanks to the cookie which is exchanged between the client and server every request (this works with HTTP headers set-cookie and cookie).
The real question is:
If you want to store user information during the navigation, then you should use session.
If your client doesn't support cookies, then you can decide to store a cookie inside each request, encoded in the URL (the server will use the URL instead of the cookie to find the right session for the request).
Then consider where you want to store your session:If your site must have high disponibility and high performance, then you must not store session inside the process but inside a database. This way you will be able to share the work among several web server.
But you will loose in simplicity (because objects you store in your session must be serializable), and you have one more round trip between your webserver and your database server.
I was always confused between LocalStorage, SessionStorage and Cookie, but not anymore.
Just link the words are self explainable what they suppose to do.
LocalStorage: Local Storage, what does that mean, just thing you don't know anything about technology, but by the itself you can guess.
It is some storage which stores data locally.
that what it is.
IT stores data in Browser without any expiration until user clear it through JavaScript code or Clear browser cache.
Session Storage: It seems like it also stores data but related to a session then how different it is from localStorage?
The main difference is your session storage data will be deleted once the session is finish or browser tab is closed or the browser is closed.
You can just try in browser console by setting
localStorage.setItem('name' , 'alex')
sessionStorage.setItem('session','seesion value')
and then close tab and open again, you can still find localStorage data but not sessionStorage data.
Cookie: So this is totally different from the above two.
A cookie generally used for the server-side purpose.
Stores data that has to be sent back to the server with subsequent
requests.
Its expiration varies based on the type and the expiration
duration can be set from either server-side or client-side (normally
from server-side).
Cookies are primarily for server-side reading (can
also be read on client-side), localStorage and sessionStorage can
only be read on client-side.
Size must be less than 4KB.
Cookies can
be made secure by setting the httpOnly flag as true for that cookie.
This prevents client-side access to that cookie
You should not use the Cache-object to cache session data, for the cache is shared between all users. Instead you could use Asp.Net Profile properties to store your data or you could add an event handler to the Session_End event and store the data if the user leaves the computer for too long.
Cookie is a piece of information shared between co-operating pieces of software, by storing client-specific information on the client's machine and later retrieved to obtain the state information.
chose the term "cookie" as "a cookie is a well-known computer science term that is used when describing an opaque piece of data held by an intermediary". The term opaque here implies that the content is of interest and relevance only to the server and not the client. The browser will automatically include the cookie in all its subsequent requests to the originating host of the cookie. A cookie has a name and a value, and other attribute such as domain and path, expiration date, version number, and comments. for more
Cookie Version:
Cookie: cookie-name=cookie-value; Comment=text; Domain=domain-name; Path=path-name; Max-Age=seconds; Version=1; Secure
Server-side session data can store large data and a client-side cookie data are limited in size sent from a website to server, cookies usually contains reference code by this saving data transfer size. Session closes as soon as browser closed, but cookies are exist longer. Browser sends a session ID to the server as a URL param, cookie, or even HTTP headers.
Cache is a hardware or software component that stores data so future requests for that data can be served faster; the data stored in a cache might be the result of an earlier computation, or the duplicate of data stored elsewhere.
Cookies are stored in browser as a text file format.It is stored limit amount of data.It is only allowing 4kb[4096bytes].It is not holding the multiple variable in cookies.
we can accessing the cookies values in easily.So it is less secure.The setcookie() function must appear BEFORE the tag.
Sessions are stored in server side.It is stored unlimit amount of data.It is holding the multiple variable in sessions. we cannot accessing the cookies values in easily.So it is more secure.

Resources