Prevent multiple login using the same user name and password

前端 未结 12 2575
栀梦
栀梦 2020-11-29 22:03

I am developing an application that needs to prevent multiple login using the same user name and password.

If it happens on the same machine then obviously we need t

相关标签:
12条回答
  • 2020-11-29 22:15

    Maybe overly simplified, but hey... it works for me in Web2Py:

    Only on successful login, I am writing the SessionID (response.session_id) in the auth_membership table. On the landing page (index page) I check whether the current response.session_id is equal to the SessionID coming from the DB. If so - all is fine. If not - (the "older" , first) user is politely logged out.

    The above works since with each login a NEW response.session_id is created and stored in the DB. The checking is done only on the landing page (which in my app is the most important one, initiating many other functions), so not too many DB hits for the above. The above is not dependent on the user logging out. No IP address is involved (which others have mentioned, suffers from its own issues) It allows only ONE user to be logged in at a time and it logs out the "older" user.

    Hope it helps NeoToren

    0 讨论(0)
  • 2020-11-29 22:18

    Create one table in your database — let's call it [online_users] — with three fields:

    [online_users]
    1. username
    2. login_time
    3. logout_time
    

    Whenever a user logs in, insert the user's name and the login time into [online_users].

    On all pages which require users to log in, place this condition: check [online_users] to see if the user's logout_time is blank or not.

    Whenever a user presses a logout button, set the logout_time in [online_users] for that user's name.

    If someone tries to log in with an active username and password, check for username and logout_time and display a message stating that the user is already logged in. And, most importantly, set logout_time to MULTIPLELOGIN for that user.

    If that user is logged in on any other machine, then if he refreshes or navigates to another page the site will tell him that he has been logged out. Then, the user can be redirected to the homepage of the site.

    0 讨论(0)
  • 2020-11-29 22:19

    This can be easily enforced if you have session. For each browser login, you should create a session record in session DB. The session ID can be used as authentication cookie. The session DB also has an index with username. At login, you can query the database to check how many sessions are there. We actually allows one session for each type. For example, user can have a login from mobile phone and another one from browser. But it can't have 2 browser sessions.

    To solve the problem you mentioned. You have 2 options,

    1. Have a very short session timeout (like 5 minutes) and extend session on every use. This way, user will be automatically logged out if leaving without logging out.

    2. Bump the other session. The new session bumps the old session. The bumped session stays in DB with a special flag for 24 hours. We display a message to tell user the other session is being bumped and displays time and IP. This way, user will get notified if their account is being compromised.

    0 讨论(0)
  • 2020-11-29 22:20

    You could store some sort of session-id for the user when logging in. When the user logs out or when the session expires, you remove that information again.

    When a user tries to log in, and you already have a session-id stored for this user, let the user confirm that, and then invalidate the old session.

    A user will certainly want to login again immediately if the browser crashed or something like that, so letting the user wait for the session to expire might be annoying.

    Does this make sense for your application?

    0 讨论(0)
  • 2020-11-29 22:22

    If user close the browser without logout.

    Particularly this case is hard and not reliable to detect. You could use the beforeunload event in Javascript, but you're fully dependent on whether the browser has JS enabled and the particular browser supports this non-standard event (e.g. Opera doesn't). That's also one of the major reasons that I'd suggest to just logout the previously logged in user instead of preventing the login. That's also more user-friendly and secure for the case that the user "forgot" to logout from the other computer.

    Easiest way is to let the User have a static Map<User, HttpSession> variable and let it implement HttpSessionBindingListener (and Object#equals() and Object#hashCode()).

    public class User implements HttpSessionBindingListener {
    
        // All logins.
        private static Map<User, HttpSession> logins = new HashMap<User, HttpSession>();
    
        // Normal properties.
        private Long id;
        private String username;
        // Etc.. Of course with public getters+setters.
    
        @Override
        public boolean equals(Object other) {
            return (other instanceof User) && (id != null) ? id.equals(((User) other).id) : (other == this);
        }
    
        @Override
        public int hashCode() {
            return (id != null) ? (this.getClass().hashCode() + id.hashCode()) : super.hashCode();
        }
    
        @Override
        public void valueBound(HttpSessionBindingEvent event) {
            HttpSession session = logins.remove(this);
            if (session != null) {
                session.invalidate();
            }
            logins.put(this, event.getSession());
        }
    
        @Override
        public void valueUnbound(HttpSessionBindingEvent event) {
            logins.remove(this);
        }
    
    }
    

    When you login the User as follows:

    User user = userDAO.find(username, password);
    if (user != null) {
        request.getSession.setAttribute("user", user);
    } else {
        // Show error.
    }
    

    then it will invoke the valueBound() which will remove any previously logged in user from the logins map and invalidate the session.

    When you logout the User as follows:

    request.getSession().removeAttribute("user");
    

    or when the session is timed out, then the valueUnbound() will be invoked which removes the user from the logins map.

    0 讨论(0)
  • 2020-11-29 22:26

    I would simply suggest using a security framework to handle all these details for you. Spring Security, for example, is fairly easy to integrate into an existing project, can be customised quite heavily if needs be - and most importantly, it has built-in support for detecting and controlling concurrent logins.

    Don't reinvent the wheel when it's not needed, else you'll end up spending a good bit of time to create a bumpy wheel.

    0 讨论(0)
提交回复
热议问题