Just wondering what the best way to store user login data on successful login in my application. I.e. when logged in at the moment I do something like this in my login script
Session("loggedIn") = "Yes"
Session("userName") = reader_login("useremail").ToString()
Session("userId") = reader_login("user_ID").ToString()
Ses开发者_JS百科sion("firstName") = reader_login("firstName").ToString()
Session("lastName") = reader_login("lastName").ToString()
And then I use these session variables on my scripts, but just noticed that every time I want to use some of these session variables I do need to check if they are nut null before calling them, seems a bit clumsy to repeat these for a lot of my .aspx pages. Is there a better way to do this ?
EDIT :
Also I am wondering why do I need to add the IS NUll check for the session on each script I use session variables I put the check in the master page but noticed I still get null exception in my usercontrol which is referenced in my master page but does not have the IS null check
Session is not the way to check whether user is authenticated or not. Session may be cleared on demand by administrator when clearing app pool, or by the low memory on server. You won't wish to log out user in such cases. The builtin and reccommended way for doing this in ASP.NET is storing data in authentication cookie. Once the user is logged in, you issue the cookie that contains all the data, including user id, name, etc. And then, you don't have to check every property in session for null, more simple - you just check if the user is authenticated - then you've got the data, else -not. And the other benefit, if you substitute builtin principal with custom one, you can define strongly typed object that holds user data, no more casting from objects extracted from session. Here're the examples for defining custom principal with forms authentication
First, let's define custom MyIdentity and MyPrincipal
public class MyIdentity : IIdentity
{
private FormsAuthenticationTicket _Ticket;
private int _userId = 0;
public FormsAuthenticationTicket Ticket
{
get { return _Ticket; }
}
public string Name
{
get { return _Ticket.Name; }
}
public int UserId
{
get
{
if (_userId == 0)
_userId = Convert.ToInt32(_Ticket.UserData.Split("|".ToCharArray())[0]);
return _userId;
}
}
public Identity(FormsAuthenticationTicket ticket)
{
this._Ticket = ticket;
}
public string AuthenticationType
{
get { return "Custom"; }
}
public bool IsAuthenticated
{
get { return UserId > 0; }
}
}
Then the MyPrincipal that holds MyIdentity
public class MyPrincipal : IPrincipal
{
private MyIdentity _Identity;
public Principal(MyIdentity identity)
{
_Identity = identity;
}
public IIdentity Identity
{
get { return _Identity; }
}
public bool IsInRole(string role)
{
return false;
}
}
Then substitute original forms user with the custom one. In Global.asax
private void Application_OnPostAuthenticateRequest(object sender, EventArgs e)
{
IPrincipal usr = HttpContext.Current.User;
// If we are dealing with an authenticated forms authentication request
if (usr.Identity.IsAuthenticated && usr.Identity.AuthenticationType == "Forms")
{
FormsIdentity formsIdentity = usr.Identity as FormsIdentity;
// Create a CustomIdentity based on the FormsAuthenticationTicket
IIdentity identity = new MyIdentity(formsIdentity.Ticket);
IPrincipal principal = new MyPrincipal(identity);
// Attach the CustomPrincipal to HttpContext.User and Thread.CurrentPrincipal
HttpContext.Current.User = principal;
Thread.CurrentPrincipal = principal;
}
}
Define method for issuing forms authentication ticket. Later, the custom MyIdentity class will extract userId and other methods from userData.
public static HttpCookie GetAuthCookie(string userName, string userData, bool createPersistentCookie, HttpSessionStateBase session)
{
HttpCookie authCookie = FormsAuthentication.GetAuthCookie(userName, createPersistentCookie);
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(authCookie.Value);
FormsAuthenticationTicket newTicket = new FormsAuthenticationTicket(ticket.Version, ticket.Name, ticket.IssueDate, ticket.Expiration, ticket.IsPersistent, userData, session.SessionID);
authCookie.Value = FormsAuthentication.Encrypt(newTicket);
return authCookie;
}
When the user is checked and is authenticated, return them authentication cookie
Response.Cookies.Add(AuthenticationCookie.GetAuthCookie(model.UserName, GetUserInfo(model.UserName, passwordHash), model.RememberMe, Session));
//GetUserInfo returns | separated string of user datas. "userId|userName|firstName|lastName" for example.
And at last, using all of the above in code
if(User.Identity.IsAuthenticated)
{
int userId = ((MyIdentity)User.Identity).UserId;
}
This may seem the larger code, but in runtime it'll give much more benefits than storing all the data in session. The main of them are null checking and casting every time.
You could load this through a single object which you put in the Session. This will remove all your strings as you can just set properties. Also you can check if the object is available in the session, if it's not the user is not logged in?
public class CurrentUserObject
{
public string UserName { get; set; }
public string UserID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public CurrentUserObject(string userName, string userID, string firstName, string lastName)
{
UserName = userName;
UserID = userID;
FirstName = firstName;
LastName = lastName;
}
}
You can instantiate this object and store it in Session("CurrentUser") or something. If you request this session variable and it turns out to be null, your user is not logged in. I would advise you to do this in a master page or something by the way to avoid duplication of this code.
you don't have to store "loggedIn" in session. you can use Session["userName"] to check, if it is null, not logged in; not null, logged in.
try to use one session item to track user login status, such username or userid.
also you can encapsule the logic into a method such as
static bool CheckLogin(HttpSession sessionState, out username, out userId, out firstName, out LastName);
FYI
may be you need to use caching in your application because you are going to check if null or not every time i think for save use data caching will be better and here are some links :
http://msdn.microsoft.com/en-us/library/xsbfdd8c(v=vs.71).aspx
http://msdn.microsoft.com/en-us/library/ms972379.aspx
http://www.exforsys.com/tutorials/asp.net/caching-in-asp.net.html
http://www.codeproject.com/KB/web-cache/cachingaspnet.aspx
Hope it helps mark as answered if it helps :)
精彩评论