I am implementing a custom ticket system using the Application_PostAuthenticateRequest
method in my global.asax
file (ASP.NET MVC). I'm wondering what the overhead for this kind of thing is - since it will deserialize some information on every request. It generates a cookie of around 1.8 kb, which is a ton - but is that a better alternative than frequent database trips?
Information being deserialized
- User Id (int)
- Roles (string[])
- Email (string)
- Associated Ids (int[]) // (hard to describe what these are, but each user will have around 3 of them)
It seemed smarter to implement a custom FormsAuthenticationTicket
system than to continuously do round-trips to the database based on User.Identity.Name
. But I'm just worried that this constant deserialization is very inhibitive. But it looks something like this...
protected void Application_PostAuthenticateRequest(object sender, EventArgs e)
{
HttpCookie authCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
if (au开发者_JAVA技巧thCookie != null)
{
string encTicket = authCookie.Value;
if (!String.IsNullOrEmpty(encTicket))
{
// decrypt the ticket if possible.
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(encTicket);
var userData = Deserializer.Deserialize(ticket);
UserPrincipal principal = new UserPrincipal(userData);
HttpContext.Current.User = principal;
}
}
}
Here is the class being serialized as UserData
in the FormsAuthenticationTicket
.
[Serializable]
public class MembershipData
{
public string Email
{
get;
set;
}
public int Id
{
get;
set;
}
public string[] Roles
{
get;
set;
}
public int[] Ancillary
{
get;
set;
}
}
I know this question is a bit old at this point and already has an accepted answer, but I'd like to throw in my thoughts and how we currently do things with a similar setup.
Originally, we were going through the same process you were and included a fair bit of user data in the cookie. This process did cut down on our database trips, but eventually we hit a bug wherein some users couldn't log in at all while others could. Turns out that the cookie was silently being dropped when it went over a certain size due to our serialized data.
Our current process is a two-tiered caching system instead. We store the user's database ID in the cookie as the User.Identity.Name
and then on PostAuthenticateRequest, we try to retrieve the user info from a local ASP.net cache, falling back to a distributed Redis cache. The local cache is in-proc and stored for 15 seconds (so repeated requests don't require going across the wire to Redis). Redis cache is stored for a day, and invalidated on update. If both of those are misses, we then load the information from SQL Server.
We then drop that user information into a custom IPrincipal and everything works like a charm. This seems to work pretty well for us in a reasonably high-usage website.
I would recommend you measuring the performance but I would expect that the cookie approach will be faster than doing roundtrips to the database. You could also simplify the serialization and make it as fast as possible by using a comma delimited or some special character delimited string. Here is how I would rank different operations in terms of performance:
- in-process communication
- inter-process communication
- inter-network communication
精彩评论