Empêcher plusieurs de connexion en utilisant le même nom d'utilisateur et mot de passe

je développe une application qui doit empêcher la connexion multiple en utilisant le même nom d'utilisateur et mot de passe.

si cela se produit sur la même machine, alors évidemment nous devons faire quelque chose avec la session utilisateur, mais cela devrait aussi empêcher si elles sont connectées sur des machines différentes en utilisant le même nom d'utilisateur et mot de passe.

nous devons garder à l'esprit les choses suivantes:

  1. Si l'utilisateur ferme le navigateur sans vous déconnecter.
  2. Heure de la session If hors.

je vous serais reconnaissant de toute aide sur ce.

14
demandé sur BalusC 2009-12-19 08:46:51

11 réponses

Si l'utilisateur ferme le navigateur sans vous déconnecter.

particulièrement ce cas est difficile et pas fiable à détecter. Vous pouvez utiliser le beforeunload l'événement dans Javascript, mais vous êtes entièrement dépendant si le navigateur a activé JS et le navigateur particulier soutient cet événement non standard (par exemple Opera ne le fait pas). C'est aussi l'une des principales raisons pour lesquelles je suggère de simplement déconnecter l'utilisateur déjà connecté au lieu d'empêcher la connexion. C'est aussi plus convivial et sécurisé pour le cas où l'utilisateur a "oublié" de vous déconnecter à partir de l'autre ordinateur.

la façon la plus facile est de laisser le Userstatic Map<User, HttpSession> variable et de le laisser mettre en œuvre HttpSessionBindingListener (et Object#equals() et 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);
    }

}

lorsque vous vous connectez au User comme suit:

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

alors il va invoquer le valueBound() qui supprimera tout utilisateur déjà connecté logins cartographier et invalider la session.

quand vous déconnectez le User comme suit:

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

ou lorsque la session est expirée, puis le valueUnbound() sera invoqué ce qui supprime l'utilisateur de logins carte.

25
répondu BalusC 2009-12-19 12:29:44

Créer une table dans votre base de données - appelons [online_users] - avec trois champs:

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

Chaque fois qu'un utilisateur se connecte, insérer le nom de l'utilisateur et l'heure de connexion dans [online_users].

sur toutes les pages qui demandent aux utilisateurs de se connecter, placez cette condition: cochez [online_users] pour voir si l'utilisateur logout_time est vierge ou non.

Chaque fois qu'un utilisateur appuie sur un bouton de déconnexion, définissez logout_time[online_users] pour ce nom d'utilisateur.

Si quelqu'un essaie de connecter avec un nom d'utilisateur et le mot de passe, vérifiez username et logout_time et afficher un message indiquant que l'utilisateur est déjà connecté. Et, plus important encore, set logout_timeMULTIPLELOGIN pour l'utilisateur.

Si cet utilisateur est connecté sur une autre machine, puis si il actualise ou accède à une autre page du site lui dire qu'il a été déconnecté. Ensuite, l'utilisateur peut être redirigé vers la page d'accueil du site.

5
répondu mastermind4242 2011-12-16 21:36:02

prendre un champ supplémentaire dans la table avec le nom de colonne dire "IsLoggedIn" comme champ bit et le mettre à true jusqu'à ce que l'utilisateur est connecté. Dès que l'utilisateur se déconnecte définie sur false. Cela doit également être fait pour la durée d'expiration de la session. Dès que la session expire, ce champ doit être défini à false automatiquement en utilisant triggers ou SP call

bonne solution est toujours la bienvenue

3
répondu Shantanu Gupta 2009-12-19 06:00:06

je conseillerais également pour la solution de Shantanu Gupta-avoir une colonne de base de données indiquant l'utilisateur est actuellement enregistré, et mettre à jour cette colonne en conséquence.

afin de "capturer" expiration de session, vous devez définir dans votre web.xml:

<listener>
   <listener-class>com.foo.MySessionListener</listener-class>
</listener>

MySessionListener est la mise en œuvre de l' HttpSessionListener interface (fournie par L'API Servlet).

2
répondu Bozho 2009-12-19 07:05:53

je suggérerais simplement d'utiliser un cadre de sécurité pour gérer tous ces détails pour vous. Sécurité De Printemps