Bonne façon D'utiliser la fonctionnalité "Remember me" en PHP

Court

travailler sur le système de connexion et essayer d'implémenter la fonctionnalité remember me.

récemment, j'ai fait des recherches sur ce sujet, j'ai lu un tas d'articles, de billets, d'histoires, de romans, de contes de fées (je les appelle ainsi, parce que certains d'entre eux ne contiennent même pas une ligne de code, juste des tas de mots) sur les vulnérabilités des cookies comme la fixation, le détournement ... etc.

Et a décidé d'atteindre les objectifs suivants

  1. pour régler le délai entre les tentatives de connexion (pour prévenir les attaques de bruteforce) et pour limiter les tentatives Compter
  2. Pour régénérer l'id de session sur presque toutes les opérations

Mais je suis vraiment confus au sujet de mon problème principal: Quelle est la bonne façon, pour "se souvenir de moi" fonctionnalité? pour utiliser les cookies / session / base de données?

et s'il vous plaît expliquez votre idée sur le code.(Je ne peux pas comprendre clairement sans code)

détaillé

Actuellement, mon code ressemble que

lors de la connexion j'utilise la fonction suivante pour configurer les cookies et la session

protected function validateUser($userid, $ckey=0, $rememmber=0) {
    session_start();
    session_regenerate_id(true); //this is a security measure
    $_SESSION['user_id'] = $userid;
    $_SESSION['HTTP_USER_AGENT'] = md5($_SERVER['HTTP_USER_AGENT']);
    if (isset($remember) && $rememmber == 'on') {
        setcookie("user_id", $_SESSION['user_id'], time() + 60 * 60 * 24 * COOKIE_TIME_OUT, "/");
        setcookie("user_key", sha1($ckey), time() + 60 * 60 * 24 * COOKIE_TIME_OUT, "/");
    }
    return true;
}

puis sur les pages utilisateur sécurisées, en vérifiant user_id à l'aide de user_id récupérer toutes les données importantes sur l'utilisation de db

public function protect() {
        session_start();

        /* Secure against Session Hijacking by checking user agent */
        if (isset($_SESSION['HTTP_USER_AGENT'])) {
            if ($_SESSION['HTTP_USER_AGENT'] != md5($_SERVER['HTTP_USER_AGENT'])) {
                $this->signout();
                exit;
            }
        }

// before we allow sessions, we need to check authentication key - ckey and ctime stored in database

        /* If session not set, check for cookies set by Remember me */
        if (!isset($_SESSION['user_id'])) {
            if (isset($_COOKIE['user_id']) && isset($_COOKIE['user_key'])) {
                /* we double check cookie expiry time against stored in database */

                $cookie_user_id = $_COOKIE['user_id'];
                               $stmt = $this->db->prepare("select `ckey`,`ctime` from `users` where `id` =?") or die($this->db->error);
            $stmt->bind_param("i", $cookie_user_id) or die(htmlspecialchars($stmt->error));
            $stmt->execute() or die(htmlspecialchars($stmt->error));
            $stmt->bind_result($ckey, $ctime) or die($stmt->error);
            $stmt->close() or die(htmlspecialchars($stmt->error));
                // coookie expiry
                if ((time() - $ctime) > 60 * 60 * 24 * COOKIE_TIME_OUT) {
                    $this->signout();
                }
                /* Security check with untrusted cookies - dont trust value stored in cookie.       
                  /* We also do authentication check of the `ckey` stored in cookie matches that stored in database during login */

                if (!empty($ckey) && is_numeric($_COOKIE['user_id']) && $_COOKIE['key'] == sha1($ckey)) {
                    session_regenerate_id(); //against session fixation attacks.

                    $_SESSION['user_id'] = $_COOKIE['user_id'];
                    $_SESSION['HTTP_USER_AGENT'] = md5($_SERVER['HTTP_USER_AGENT']);
                } else {
                    $this->signout();
                }
            } else {
                if ($page != 'main') {
                    header('Location:' . wsurl);
                    exit();
                }
            }
        }
15
demandé sur Tural Ali 2012-01-18 12:47:31

4 réponses

mais je suis vraiment confus au sujet de mon problème principal: quelle voie est appropriée, pour "se souvenir de moi" fonctionnalité? pour utiliser les cookies / session / base de données?

Http est un protocole apatride. Jeton d'authentification doit persister à maintenir l'état. La bonne façon est d'utiliser session. Maintenant, comment suivez-vous la session? C'est à vous. Mais les cookies ne sont pas mauvais.

dans la session vous pouvez enregistrer un hachage créé à partir de différents critères de navigateur (agent utilisateur, os, résolution d'écran, etc) à vérifiez si le token provient du même environnement. Plus vous économisez de critères, plus il sera difficile de détourner. Btw vous avez besoin de JavaScript pour saisir les informations supplémentaires à chaque fois.

2
répondu Shiplu Mokaddim 2012-01-18 09:46:00

pour définir le délai entre les tentatives de connexion (pour prévenir les attaques de bruteforce) et pour limiter les tentatives de Compte

ainsi vous fournissez une méthode pour DOS par compte?

Pour régénérer l'id de session sur presque toutes les opérations

euh, non. C'est en fait probablement à l'encontre de l'objet. Vous devriez toujours générer un nouvel id lorsque le courant id est expiré ou lorsque l'utilisateur est authentifié - sinon, laissez-le seul.

mais je suis vraiment confus au sujet de mon problème principal: quelle voie est appropriée, pour "se souvenir de moi" fonctionnalité? pour utiliser les cookies / session / base de données?

depuis que vous avez besoin de conserver un token sur le client, cela signifie des cookies (à moins que vous n'ayez envie d'écrire quelque chose de vraiment compliqué en utilisant le stockage local). Comme vous ne voulez pas exposer des données via le cookie / rendre la falsification simple, cela signifie qu'il devrait être une valeur aléatoire. Et pour réconcilier la valeur aléatoire stockée, cela signifie stocker les données serverside-probablement dans une base de données car il doit être possible de faire référence aux données sur la base de l'identifiant de l'utilisateur ou sur la base de la valeur aléatoire.

alors que vous pourriez juste utiliser une session Non-expirante (ou de très longue durée), je resterais loin de cela - les données vont boule de neige - et c'est une bonne idée de renouveler les données de session une fois de temps en temps.

vous devez également tenir compte du scénario où un utilisateur veut que vous vous souvenez d'elle sur 2 ordinateurs différents. Si vous n' tenez un seul token' remember me ' pour chaque compte, alors soit vous devrez utiliser la même valeur pour les deux clients ou supprimer l'ancien token lorsque vous en créez un nouveau (c'est-à-dire que l'utilisateur ne peut être mémorisé que sur une seule machine).

veuillez expliquer votre idée sur le code. Je ne peux pas comprendre clairement sans code

Non. Je suis payé pour écrire du code; Si vous voulez m'écrire le code pour vous, alors vous aurez besoin pour me payer. Et le code prendra beaucoup plus d'espace et de temps que la description ci-dessus.

8
répondu symcbean 2012-01-18 09:29:50

si vous voulez un exemple de fonction "remember me" avec du code, vous pouvez consulter ma bibliothèque PHP à https://github.com/gbirke/rememberme

3
répondu chiborg 2012-01-18 08:53:43
<form action="" method="post" id="frmLogin">
<div class="error-message"><?php if(isset($message)) { echo $message; } ?></div>    
<div class="field-group">
    <div><label for="login">Username</label></div>
    <div><input name="member_name" type="text" value="<?php if(isset($_COOKIE["member_login"])) { echo $_COOKIE["member_login"]; } ?>" class="input-field">
</div>
<div class="field-group">
    <div><label for="password">Password</label></div>
    <div><input name="member_password" type="password" value="<?php if(isset($_COOKIE["member_password"])) { echo $_COOKIE["member_password"]; } ?>" class="input-field"> 
</div>
<div class="field-group">
    <div><input type="checkbox" name="remember" id="remember" <?php if(isset($_COOKIE["member_login"])) { ?> checked <?php } ?> />
    <label for="remember-me">Remember me</label>
</div>
<div class="field-group">
    <div><input type="submit" name="login" value="Login" class="form-submit-button"></span></div>
</div>       

session_start();
if(!empty($_POST["login"])) {
    $conn = mysqli_connect("localhost", "root", "", "blog_samples");
    $sql = "Select * from members where member_name = '" . $_POST["member_name"] . "' and member_password = '" . md5($_POST["member_password"]) . "'";
    $result = mysqli_query($conn,$sql);
    $user = mysqli_fetch_array($result);
    if($user) {
            $_SESSION["member_id"]         = $user["member_id"];

            if(!empty($_POST["remember"])) {
                setcookie ("member_login",$_POST["member_name"],time()+ (10 * 365 * 24 * 60 * 60));
                setcookie ("member_password",$_POST["member_password"],time()+ (10 * 365 * 24 * 60 * 60));
            } else {
                if(isset($_COOKIE["member_login"])) {
                    setcookie ("member_login","");
                }
                if(isset($_COOKIE["member_password"])) {
                    setcookie ("member_password","");
                }
            }
    } else {
        $message = "Invalid Login";
    }
}
-1
répondu Niby 2018-09-05 05:50:41