简体   繁体   中英

Check if user is already logged in asp.net website

I am developing a website where in user is required to login to the system to be able to use it. The current functionality is: When user enters username and password, a check is made in DB to check if that user exists and if he has entered a correct password. Only then allow that user to login.

It was fine till this point, now client wants to add one more functionality to the logging feature, ie client would like to restrict only 1 session for that user to exists.

ie. if user1 is logged in from one browser of the PC then he should not be allowed to login from another system or another browser of the same PC.

How do I do that? I was planning to do it using a bit field in my database which will be set when user logs in 1st time. And if he tries to logging 2nd time check that field and allow to login only if bit field is not set.

But I feel it will cause issues,

1) if user by mistake closes the tab of the browser and tries to log in again he will not able to do so as the bit field will still be set in DB

2) when will the set field will have be cleared if users closes the browser by mistake?

If there is any other way to implement it then you are free to point me in a correct direction.

As pointed by some of the fellow members there are duplicates to this question but those questions are not really what I am looking for, as they are using form based authentication and I am not .

You can add a column to userTable like IsLoggedIn . at login time you can change to true and on Session_End event on global.asax change it to false

To give more details about my comment:

Step 1

Create a Sessions table that contains the following fields:

SessionId ( Primary Key )                       char(24)
UserId ( Foreign Key to Users table )           int
LoginDate                                       datetime

Step 2

Create your Session class.

public class Session {
    public string Sessionid { get; set; }
    public int UserId { get; set; }
    public DateTime LoginDate { get; set; }
}

Step 3

If you have a function called DoLogin .

public void DoLogin() {
   //validation commes here...

   //create your session
   Session["User"] = user; //user is your User class object

   //create session class for db
   Session session = new Session();
   session.SessionId = ""; //you can generate here a 24 character string
   session.UserId = user.Id;
   session.LoginDate = DateTime.Now;

   db.Add(session); //add session to db
}

Step 4

Create a function to check if user is already loggedin.

public bool IsLoggedIn(User user) {
   Session session = db.GetSession(user.Id); //Get session of the user

   if(session != null)
   {
      return true;
   } else {
      return false;
   }
}

Do not try to solve such problems by storing the values in datatbase instead go for a session Kind of approach.

In the login page or your default page take the user that is logged in using a session (ie Session["Username"]="Some logged in User")

now on load of every manager page check the validity of the session as below

if(!mCheckStatusOfSession())
{
Response.Redirect("To Login Page")
}

protected void mCheckStatusOfSession{
               if (Application[Session["UserName"].ToString()] == null)
                {
                    return false;
                }
                else
                {
                Application[Session["UserName"].ToString()].ToString();
                    if (strID == Session.SessionID.ToString())
                    {
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                }
}

1) User logs in, we check the Cache using username+password as the key for the Cache Item. If the Cache item exists, we know that the login is already in use, so we kick them out. Otherwise, we authenticate them (database, etc) and let them in.

2) After we have let them in, we set a new Cache item entry with a key consisting of their username+password, with a sliding expiration equal to the current Session Timeout value. We can also set a new Session variable, Session["user"], with a value of the username+password, so that we can do continuous page request checking and Cache updating on every page request during the user's session. This gives us the infrastructure for "duplicating" the missing Session_End functionality.

3) Now we need a way to update the Cache expiration on each page request. You can do this very elegantly in the Application_PreRequestHandlerExecute handler in Global, because the Session object is available and "live" in this handler. In addition, this event is fired on every page request, so we don't need to put a single line of extra code in any of our pages. We use the Session["user"] value to get this user's key to retrieve their Cache Item, thus resetting it and automatically setting the sliding expiration to a fresh timeout value. Whenever you access a Cache item, its SlidingExpiration property (if properly configured) is automatically updated. When a user abandons their session and no pages are requested for a period of time, the SlidingExpiration of their Cache Item eventually expires, and the item is automatically removed from the Cache, thereby allowing somebody with the same username and password to log in again. No fuss, no muss! Works with InProc, StateServer and SQL Server Session modes!

Reference Articles : 1 , 2 , 3

This is how I managed to do it with the help of link provided by @Satinder singh .

Global.asax.cs

    protected void Application_Start(object sender, EventArgs e)
    {
        Application["UsersLoggedIn"] = new System.Collections.Generic.List<string>();
    }

    protected void Session_End(object sender, EventArgs e)
    {
        // NOTE: you might want to call this from the .Logout() method - aswell -, to speed things up
        string userLoggedIn = Session["UserLoggedIn"] == null ? string.Empty : (string)Session["UserLoggedIn"];
        if (userLoggedIn.Length > 0)
        {
            System.Collections.Generic.List<string> d = Application["UsersLoggedIn"]
                as System.Collections.Generic.List<string>;
            if (d != null)
            {
                lock (d)
                {
                    d.Remove(userLoggedIn);
                }
            }
        }
    }

Login.aspx.cs

protected bool Login(string userId)
    {
        System.Collections.Generic.List<string> d = Application["UsersLoggedIn"]
            as System.Collections.Generic.List<string>;
        if (d != null)
        {
            lock (d)
            {
                if (d.Contains(userId))
                {
                    // User is already logged in!!!
                    string userLoggedIn = Session["UserLoggedIn"] == null ? string.Empty : (string)Session["UserLoggedIn"];
                    if (userLoggedIn == user_id)
                    {
                        Session["UserLoggedIn"] = user_id;
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                }
                else
                {
                    string userLoggedIn = Session["UserLoggedIn"] == null ? string.Empty : (string)Session["UserLoggedIn"];

                    if (userLoggedIn != user_id)
                    {
                        d.Add(userId);
                    }
                }
            }
        }
        Session["UserLoggedIn"] = userId;
        return true;
    }

With above code, I am allowing any user to be logged in at any time only once. I used session variable to check if the request is from same browser, if so, I am allowing him/her to login else throwing a message "You are already logged in from another system".

May be the old answers were worth observing at that time. However, I have currently resolved the problem using User.Identity.IsAuthenticated . I have EntityFramework 6 and using Dot Net Framework 4.7.2 and MVC 5. You need to set FormsAuthentication.SetAuthCookie(PrimaryKey, false); when user is loggedIn. Here, PrimaryKey is the key that you can use throughout the session for identification of the user using User.Identity.Name . Also, when user log out of the application, you will call FormsAuthentication.SignOut(); This actually saves the information in the browser cookie so that you can reuse the information.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM