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:
- Si l'utilisateur ferme le navigateur sans vous déconnecter.
- Heure de la session If hors.
je vous serais reconnaissant de toute aide sur ce.
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 User
static 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.
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_time
MULTIPLELOGIN
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.
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
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>
Où MySessionListener
est la mise en œuvre de l' HttpSessionListener
interface (fournie par L'API Servlet).
je suggérerais simplement d'utiliser un cadre de sécurité pour gérer tous ces détails pour vous. Sécurité De Printemps