2016-06-10 41 views
1

我搜索了一下,發現了有關我的問題的一千個問題,我試圖解決,但沒有得到幫助。所以我打開這個線程爲我的具體情況,我希望你能幫助我。登錄系統記住,怎麼辦?

我想說明一點,我在PDO中創建一個登錄系統,是一個初學者,但是我希望它總是能夠通過cookie持續登錄。

我做了幾個測試,但沒有結果。瀏覽器已關閉,必須重新輸入憑據。

我再說一遍,我已經在網站上搜索過,但還沒有設法解決。

的login.php

if (empty($_POST) === false) { 
    $username = trim($_POST['username']); 
    $password = trim($_POST['password']); 

    if (empty($username) === true || empty($password) === true) { 
     $errors[] = 'Sorry, but we need your username and password.'; 

    } else if ($users->user_exists($username) === false) { 
     $errors[] = 'Sorry that username doesn\'t exists.'; 

    } else if ($users->email_confirmed($username) === false) { 
     $errors[] = 'Sorry, but you need to activate your account. Please check your email.'; 

    } else { 

     $login = $users->login($username, $password); 

     if ($login === false) { 
      $errors[] = 'Sorry, that username/password is invalid';  
     } else { 
      $_SESSION['id'] = $login; // The user's id is now set into the user's session in the form of $_SESSION['id'] 
      $_SESSION['username'] = $usr; 

       $cookie_name = '_name_cookie_';   
       $hash = password_hash($password, PASSWORD_BCRYPT, ["cost" => 12]); // will result in a 32 characters hash 
       $cookie_time = (3600 * 24 * 30); // 30 days 
       setcookie($cookie_name, 'usr='.$usr.'&hash='.$hash, time() + $cookie_time);  


      header('Location: home.php'); 
      exit(); 
     } 
    } 
} 

類:users.php

public function login($username, $password) { 
    $this->db->query("SELECT * FROM users WHERE username = :username"); 
    $this->db->bind(':username', $username); 
    $data = $this->db->single(); 

    $hash = $data['password']; 
    $id = $data['id']; 

    #hashing the supplied password and comparing it with the stored hashed password. 
    if (password_verify($password, $hash)) { 
     return $id; 
    }else{ 
     return false; 
    } 
} 

注意:在目前的形式我不小心檢查集成 「記住我」 ,我會稍後再做。

但是,我不能如何保持登錄用戶,cookie被正確插入,否則它不起作用。我該如何解決?

+0

你是否在每個文件的開頭調用session_start()?我的登錄系統的工作原理與您的想法完全相同。我可以告訴你我是如何處理會話的,但是我不知道這是否是你想要的 – JRsz

+0

這不是問題,每個頁面都會調用session_start(),但登錄將持續,但是有限。我想記錄用戶數據,所以我並不總是輸入您的詳細信息登錄。 –

回答

0

有幾種方法可以做到這一點,比其他方法更好。有一些信息,即使在這個網站上,但我會花費大致的想法。

首先,您需要某種令牌或某種東西來識別客戶端上的用戶。這通常使用$_COOKIE完成。我喜歡設置兩個單獨的cookie,一個用戶標識和一個用哈希標記,這樣即使有人可以猜到這個標記(這是不太可能的),他們也需要匹配的用戶標識。使用實例從您的代碼,這將是樣本代碼來生成說餅乾

// Define variables 
define("COOKIE_DURATION", time()+60*60*24*30); // 30 days 
$userHash = hash("sha256", $_SESSION['id'].time()); 

// Set the cookies 
setcookie("RememberMeID", $_SESSION['id'], COOKIE_DURATION); 
setcookie("RememberMeHash", $userHash, COOKIE_DURATION); 

這將使用當前時間和用戶名組合在一起,然後湊那個,所以我們可以使用它作爲一個標識符。我已經使用sha256這個,因爲它不是我們存儲的密碼,應該沒問題。

接下來,我們需要用這兩個cookie來識別用戶。因此,這些數據也必須存儲在服務器中,所以我們可以在用戶訪問網站時對其進行匹配。您可以爲此使用數據庫,例如包含此信息的單獨rememberMe表。這可能包含您之前創建的散列,以及用戶標識。所以,你需要把它插入到數據庫中。

$stmt = $pdo->prepare("INSERT INTO rememberMe (userID, userHash) VALUES (:id, :hash)"); 
$stmt->execute(array("id" => $_SESSION['id'], "hash" => $userHash)); 

然後,你可以簡單地檢查,如果這兩個Cookie被設置在一個會話沒有設置,看看數據是否匹配 - 如果確實如此,設置自己的會話!

// If we're not logged in, and the two cookies are set, we can check if something matches 
if (!isset($_SESSION['id']) && !empty($_COOKIE['RememberMeID']) && !empty($_COOKIE['RememberMeHash'])) { 
    // Check if the cookies match something in the DB... 
    $stmt = $pdo->prepare("SELECT COUNT(*) as `count`, userID FROM rememberMe WHERE userID=:id AND userHash=:hash"); 
    $stmt->execute(array("id" => $_COOKIE['RememberMeID'], "hash" => $_COOKIE['RememberMeHash'])); 
    $row = $stmt->fetch(PDO::FETCH_ASSOC); 

    // If it does, we log them in and renew the cookie 
    if ($row['count'] > 0) { 
     $_SESSION['id'] = $row['userID']; 
     setcookie("RememberMeID", $_SESSION['id'], COOKIE_DURATION); 
     setcookie("RememberMeHash", $_COOKIE['RememberMeHash'], COOKIE_DURATION); 
    } 
} 

您還可以在這個主題讀:What is the best way to implement "remember me" for a website?

+0

感謝您的回覆,我發佈了一條新評論並提供更新。 –

0

非常感謝你的幫助。我在當時繼續以這樣的方式

if (empty($_POST) === false) { 
    $username = trim($_POST['username']); 
    $password = trim($_POST['password']); 

    if (empty($username) === true || empty($password) === true) { 
     $errors[] = 'Sorry, but we need your username and password.'; 

    } else if ($users->user_exists($username) === false) { 
     $errors[] = 'Sorry that username doesn\'t exists.'; 

    } else if ($users->email_confirmed($username) === false) { 
     $errors[] = 'Sorry, but you need to activate your account. Please check your email.'; 

    } else { 

     $login = $users->login($username, $password); 

     if ($login === false) { 
      $errors[] = 'Sorry, that username/password is invalid';  
     } else { 

      if (!isset($_SESSION['id']) && !empty($_COOKIE['RememberMeID']) && !empty($_COOKIE['RememberMeHash'])) { 
       $db->query("SELECT * FROM rememberMe WHERE userID = :userID AND userHash = :userHash"); 
       $db->bind(':userID', $_COOKIE['RememberMeID']); 
       $db->bind(':userHash', $_COOKIE['RememberMeHash']); 
       $db->resultset(); 
       $row = $db->rowCount(); 

       if ($row['count'] > 0) { 
        $_SESSION['id'] = $login; 
        setcookie("RememberMeID", $_SESSION['id'], COOKIE_DURATION); 
        setcookie("RememberMeHash", $_COOKIE['RememberMeHash'], COOKIE_DURATION); 
        header('Location: home.php'); 
        exit();  
       } 
      } 
     } 
    } 
} 

雖然,我不知道在哪裏輸入第一碼和在什麼時候。實際上,插入令牌的代碼必須插入到註冊頁面中,以便註冊用戶進入數據庫?