开发者

ASP.NET how to store user login data in the APP

开发者 https://www.devze.com 2023-03-23 23:55 出处:网络
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

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 :)

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号