I am looking for a way to do fully cookie-based sessions in ASP.NET. I don't intend to store complex objects in them, just string key-value pairs.
I am looking for something similar to how the Play! framework handles sessions, it basically encodes all the session data in a cookie and takes care of encrypting/decrypting it on each request.
I don't want to have to write my own SessionStateModule for this if I can avoid it, does one exist?
Thanks
EDIT: I don't need to store more data than a cookie can handle (just a few identifiers) and I still need the key-value pairs to be specific to each session. I would like to use cookies so that no server state has to be maintained (either in process or in a database) which allows me to add more servers quite easily and also depend less on external applications (no state server/memcached/redis etc)
You won't be able to store that much data in a cookie unless you are going to create lots of them.
Given you want to work with key value pairs have considered using a cache such as memcached or redis. Or even the server cache if you are not in a web farm?
I don't think one exists: it would be too fragile because of the restrictions inherent in using cookies (notably the maximum size).
And I know this isn't answering your question, but I wouldn't implement a SessionStateModule for this. Doing so would mean that any 3rd party components that use Session, or any future maintenance programmers who use Session would possibly be storing inappropriate data (e.g. too large) in the cookie.
I'd suggest you write your own API oriented round storing key-value pairs with only primitive values (string, Int32, DateTime,...) in your cookie.
You can also make the API "cookie-aware" - e.g. set HttpCookie.Path which gives you the possibility to:
avoid sending cookies for requests that don't need them (javascript, images, ...)
have different cookies (same name but different Path) for different Areas of your application. This can help keep the cookie size down.
Related
We are building a new ASP.Net Core WebService which will provide data from existing Database.
To reduce to load on the database and improve response times I thought about caching certain objects and configurations from the database.
I found this for caching in ASP.Net Core: https://learn.microsoft.com/en-us/aspnet/core/performance/caching/memory?view=aspnetcore-2.2
What seems to be the way to go. The Article also says: Do not use external input as cache keys
My Problem now is that basically all data are depending on the user or a user input.
I am aware that caching makes only sense with objects that get often used but rarely changed.
Here an simplified example when I might want to use caching: We do have holiday / workday configuration which can by per state different. So it can vary depending on the user but 100s of users might use the same configuration.
Also there are some shared components which a lot of users share but which components are returned is depending on what is requested.
So what would be the best approach to cache such entities?
I am also open for any Idea that helps me reduce the calls to the database.
Thanks and best regards,
Marc
I think you're misunderstanding. The caution is against using external user input as cache keys. In other words, you should not take some input from the user and the set something in the cache via that:
_cache.SetString(userInput, "foo");
It's not talking about setting user input as the value, i.e.:
_cache.SetString("my cache key", userInput);
It's also not talking about segregating the cache by user:
_cache.SetString($"cache key for user {userId}", "foo");
Both of the latter scenarios are fine. It's just that allowing the user to set the key itself opens yourself up to things like potential SQL injection attacks, depending on your cache store.
Also, note that it's mostly talking about unsanitized user input. If it's something like an enum where the user can pick only from a set of defined values, then you're fine. Or, if you otherwise know that the input is not going to cause issues. For example, a zip code that you've validated only contains numbers and maybe a single dash. There's nothing a malicious user can do with that, so it's fine. However, a free form text field like "Name" would be problematic to say the least.
The documentation discourages external input as cache keys, because it might lead to too many cache entries and consume quite a lot of RAM, which will in turn have negative impact on the performance.
You need to experiment. Maybe you will not end up with too many different user input variations.
You can also consider an external caching service like Memcached, where you can use additional servers as cache. This will allow you to cache many more values and reduce your load on the db.
Is it a good idea to avoid state management techniques(session, cookies etc) in ASP.Net MVC 3.0?
If yes then is there any other alternatives available except TempData?
This would depend on your specific requirements. Session state and cookies for example are very different beasts.
If session state is a good fit to your requirements in WebForms then it's a good fit in MVC. There is no specific reason not to use it in MVC.
You basically only have 3 places you can store data, on the client (cookies/hidden values/query string), on the server (session/cache/static), in the database.
There is loads of documentation of the pros and cons of all these methods, a good starting place is:
http://msdn.microsoft.com/en-us/library/z1hkazw7.aspx
It depends.
Session and cookies were invented to solve some kind of problem, so they should be used to solve that problem.
TempData won't help much in replacing cookies - because cookies are saved on client side.
Also TempData is Session, distinction is that TempData is for redirection only. As long as TempData is quite usefull in redirection scenarios, you may wish to keep session to be enabled for these scenarios.
If you don't have session oriented scenarios (like object creation has multiple steps and after first step you can't save it to database yet), you can avoid using it, but in general it is not by itself evil.
I find that state is nicely maintained in a cache when implementing the repository pattern. In the MVC Futures project, there is also the Html.Serialize method which gives 'view state like' state storage.
http://mvccontrib.codeplex.com/
For information like items bound to a combobox that we were used to having maintained automatically for us in web forms, a good alternative here is to call off to a repository for the data. The repository maintains a reference to a cache (ideally through an interface you create like - ICache). The repository then caches this data based on for ex. the current users name, key whatever. Some prefer to have a service layer cache, but I feel by design a repository layer was meant for this.
Session is still used - if you must - it has its place. A lot of 'bad' surrounds the session, but if you need to store session specific information and your site isn't concerned with a large number of hits a day, then you can likely take the hit just fine.
TempData is great for storing status messages to show on the next request such as 'record saved successfully' so you don't lose it across the redirect and don't have to pass it on the querystring. Thats about the only thing I use it for although some use it to store data for rebinding on the next request.
IMO, the rules for session state in MVC are the same as the rules in WebForms: use it if you must, but keep your usage lightweight. If you truly have some data to track per user/session, there is no need to reinvent the wheel.
You can save your state in the database directly
I have a number of locations in a number of applications I have built where a page accepts a QueryString in the following format: http://localhost/MySite.aspx?ID=ab1cbabe-42e2-4d15-ab11-17534b829381
These pages will then take the query string, attempt to parse it and display the data that matches the guid using a database call with strongly typed values.
Example:
Guid value;
if (Guid.TryParse(Request.QueryString["ID"], out value))
{
SomeControl.Datasource = DatabaseCall(value);
SomeControl.Databind();
}
What this obviously means is that any user (provided they have the guid for the data) can technically access any other users data. Obviously predicting guids is next to an impossibility but I'm still uneasy about it.
How does everyone else deal with this problem? Is there a "correct" way? Is it even worth worrying about?
In various circumstances it absolutely is worth worrying about.
People tend to post or email URIs without stripping away the query strings
Most browsers store the whole uri including the query string in a history
Most browsers even offer autocomplete in the address bar which lets you try through already visited resources
The http request can be intercepted pretty much anywhere on its way from client to server, exposing the query string
I'd recommend some kind of user-based authentication mechanism like asp.net's membership provider.
In case you already are using some authentication, linking resource guids to their respective user ids in an association table might do the trick.
You answered your own question: "Obviously predicting guids is next to an impossibility"
However, the proper way to implement user access, is to build and manage an ACL. You can't simply rely on a unique string for that, because even if users don't guess the string, an attacker can still sniff the traffic and reuse the GUIDs they found.
I agree with #Laurent.
But - it depends on your type of business. For extreme security-related contexts such as banking, money transactions, sensitive personal data etc., I would go to an encrypted cookie, or simple - a unique key that is passed in the query string (as you asked about), but not a guid but something far longer (just make sure it's randomness is fairly hard to predict), along with a background task on the server that invalidates "tokens" that are older than X minutes, to mitigate the risk of stealing URLs.
Consider resorting to some standard mechanism such as ASP.NET Membership.
So I have never had to use cookies before but now I am making a Shopping Cart that they can keep coming back to and leaving but I want it to store what they added.
What I am wondering:
How do check if a cookie exists and then create or update it, is that the best way to think about using a cookie?
How exactly would I store the data, in particular I want to store a list of IDs like "5,6,7,8", should I just use one string for this or is there a faster/better way than reading/parsing/writing something like that? I mean I suppose I would just keep adding new_value + ',' to the end, is there an append for cookie variables?
Does the cookie have some unique identifier that I would use to be sure I don't write duplicates or something?
Note: It's easy to look up 'HOW' like for seeing the syntax but I'm really trying to grasp the 'BEST WAY' or most ideal, how it was meant to be used, or how all you programmers found is the most fruitful way to utilize them in this type of scenario.
The winning answer to this similar question suggests that you only store the user ID in the cookie. The rest goes in the database.
If you can consider other approaches besides cookies, many folks prefer using session over using cookies. For one thing, you don't always have a lot of room in a cookie.
Storing the shopping cart in a cookie means that you will have no record of what people were shopping for but didn't purchase.
OTOH, using the cookie is using the shoppers' storage space and preserving your own. That could be significant over time and a lot of shoppers.
I solved this in the past by creating a class to manage the cookies (e.g.CookieManager) with static methods I passed an HttpRequest object to.
I was trying to solve a very similar problem, so I created a Count cookie and then a cookie which stored the information I wanted to save (in your case an ID number). I only wanted to save the last 5 items a user viewed, so I would manage this in my CookieManager class, dequeuing the oldest cookie and queuing up latest. The Count cookie kept track of how many cookies I had. Obviously, this isn't very high tech or secure, but for this project that was completely unnecessary. Anything you want to be robust should be saved on a database, or elsewhere server-side.
I want to further explain why you only store a guid that maps to a userid in a cookie. There are two main reasons:
Performance. As slow as it may seem to pull data from a database, you have to remember that cookie data is not free. It has to be uploaded from the user's browser to your web server, and even high-speed broadband connections tend to have much slower upload speeds. By contrast, your database likely has a gigabit link (sometimes even faster) directly to the web server. So what you really want in your cookie for best performance is a guid that maps directly to the primary key of your database table.
Security. Data in cookies is stored in a plain text file on the user's computer. You never know where a user will access your site from; it could be a very public place that's not appropriate to keep such data.
So is there any data you can use cookies for directly? As it happens, there is. Cookies have the nice property of sticking with a particular machine and browser. These days a lot of people will access the web from more than one place. Perhaps a work computer, a home computer, a smart phone, a netbook... all of which may have different screen sizes and other peculiarities. So what you can do with a cookie is store information specific to that combination of user+location.
I have heard of people using them for keeping track of session variables, but I really want to know if there are many uses for them and under what conditions it would be beneficial to employ a hashtable vs any other data structure that can handle key value pairs, like a dictionary for example.
eg. I have heard of people putting session values in a hashtable then putting the hash table in the Session object. I just wanted to know what benefit that was.
- Is it more performant?
- Does it protect against other developers putting same name variable into the session?
Edited.
Its like asking what is the use of hammer in construction of a house... if you want it simple then hashtable just key/value pair, its up to u where to place your nail :)
A difficult question to answer, mainly because you're looking for a problem to match a solution rather than the other way around. I'll throw in my two cents though.
Session variables essentially store information for the current user's session. They're accessed by a key, so they really behave in the same way as a hashtable. They may even be implemented under the covers (partly) as a hashtable - I don't know.
The important thing to note about session variables is that they are an abstraction from the fact that web applications are stateless. What actually happens is that you save a value to session, and when you return the page, that value is saved somewhere (usually in memory or a database). The next time a request comes from that person, the variable is reloaded.
Hashtables are useful mainly for fast access to a large number of objects or values using lookup keys. Because web is stateless, and session is confined to a single user, I can't see much use for hashtables. If you need to quickly get access to a piece of data in a large collection, storing an entire hashtable at the end of a request and reloading it at the start of a request just to get quick access to an item is unlikely to be an efficient use of resources.
Depends what you mean by hash tables, for example the backend databases that drive most websites have multiple hash tables embedded into the tables (in the form of indices). Assigning data to user id's through session variables also comes to mind (or cookies for that matter). There's plenty of examples of hash table uses.
The framework I am currently developing will have a lot of socket requests, many a minute per client.
Each socket request will contain the client's identifier, which will be stored/looked up in the Hashtable.
The reason I have chosen to go down this route is the performance flexibility available through the Hashtable, which I will be able to leave for now - and tweak later on.
:)
Note that "dictionary" and "hash table" are at two different levels of abstraction. A dictionary is something that maps keys of arbitrary type to values. A hash table is one way to implement a dictionary.
Note that sometimes "hash[ table]" is used as a synonym of "dictionary", such as in Perl's %hashes.
You use a hash table when you want the performance characteristics of a hash table. Mostly you wouldn't care and would just leave it as an implementation detail of your programming language.
Note that you can implement a hash table to have (amortized randomized expected) O(1) worst case, but many implementations don't go through all the work and performance overhead to achieve that. You don't need to bother if your inputs are cryptographic hashes or outright random, as in your example of (good) session tokens, so a hash table could have less overhead as compared to a hash table implementing an arbitrary dictionary.
Try reading Wikipedia's definition of a hash table for ideas on how you might use them.
In essence, a hash table is a way of mapping a particular key to a particular value. So in the case of session variables, you might use the variable as a key and a user's ID as the value. This would allow you to map any actions taken on a particular session to a specific user (the one logged into that session) and attribute any actions to them. Again, Wikipedia has some more information on sessions.