利用 Cookie 實作登入機制

想記下來。

簡述

因為 HTTP 協議本身是「無狀態」的,所以要讓它可以記得「每個 request 之間的關聯性」才能做出登入機制。

登入的流程是這樣子:

  1. 填好帳密後送出表單 => 第一個 request
  2. Server 確認帳密無誤,重新導回首頁 => 第二個 request (回到首頁也會發一個 request)

最簡單的方式

Server 可以透過 cookie 來做設定,讓瀏覽器在下一次的 request 自動把 cookie 帶上。

拿留言板的例子來舉例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/* handle_login.php */
<?php
$sql = "SELECT * FROM users WHERE username='$username' AND password='$password'";
// 下 query
$result = $conn->query($sql);
// 有撈到資料就代表帳號密碼正確
if ($result->num_rows > 0) {
// cookie 的過期時間
$expire = time() + 3600 * 24 * 30;
// 設定 cookie
setcookie('username', $username, $expire);
// 登入成功,導回首頁
header('Location: ./index.php');
} else {
// 登入失敗,顯示錯誤訊息
header('Location: ./login.php?errorCode=2');
}
?>

當登入成功後,可以打開 devtool 看看這之間發生了什麼。

首先,Server 會回傳 Set-Cookie 這個 header,也就是 PHP 中寫入的值 username=$username

login

接著被導回首頁後,會看到 request header 就會自動把剛剛的 cookie 給帶上來:

redirect

這時候 index.php 就可以利用 cookie 的值來檢查這個 user 有沒有登入:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/* index.php */
<?php
require_once("./conn.php");
require_once("./utils.php");
// 預設值 null,代表沒有登入
$username = Null;
// 檢查 cookie
if (!empty($_COOKIE['username'])) {
// 如果 cookie 的 username 欄位有值,
// 就更新 $username 的值
$username = $_COOKIE['username'];
// 去資料庫撈出這個 user 的資料
$user = getUser($username);
// 這個 user 的暱稱
$nickname = $user['nickname'];
}
?>

最後就完成登入機制了:

result

這就是最最最基本的登入功能了,只是這個做法有個問題,就是別人可以竄改 cookie 值來假冒別人身分,這邊我另外開一篇文章來解釋,請參考 當 Cookie 被竄改會怎麼樣?

當 Cookie 被竄改會怎麼樣? mentor-program-day56
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×