close

轉錄自 http://openlyu.com/forums/index.php?topic=1930.0

這個教學會教你怎麼用 PHP 和 MySQL 來製作會員的登入頁面。
它會用 cookie 來儲存會員的 session id,但不會用 PHP 內建的 session 功能。
完成之後只需要在任何的網頁裡面包含另一個驗證檔案就可以了。

這個教學共有五個檔案:
config.php - 登入資料庫的資料
login.php - 輸入帳號和密碼的網頁
actionlogin - 驗證會員的檔案
incsession.php - 檢查會員是否已登入
test.php - 需要驗證才能登入的網頁


首先用下面的 SQL 建立你的資料庫:

 

程式碼:
CREATE TABLE susers (
    userid int(10) unsigned NOT NULL auto_increment,
    email varchar(255) NOT NULL,
    password varchar(255) NOT NULL,
    guid varchar(32),
    PRIMARY KEY (userid)
    ) TYPE=MyISAM;
    
INSERT INTO susers VALUES (
    NULL,
    'test@user.com',
    password('pass'),
    NULL
    )

上面的 test@user.com 就是會員的帳號,pass 就是它的密碼。
pass 是用 MySQL 內建的 password() 加密函式。

 

接下來建立 config.php:

程式碼:
<?php
$db_host 'localhost';
$db_user 'tutorials';
$db_pass 'pass';
$db_name 'tutorials';
?>

將上面的資料改成你登入資料庫的帳號,密碼,和資料庫。

再來將下面的資料輸入到 login.php:

程式碼:
<html>
<head><title>Login</title>
</head>
<body>

<form action="actionlogin.php" method="POST">
Email:<br />
<input type="text" name="email">
<br />
Password:<br />
<input type="password" name="password">
<br />
<input type="submit" name="submit" value="Login">
<input type="hidden" name="refer" value="<?php echo (isset($_GET['refer'])) ? $_GET['refer'] : 'index.php'?>">
</form>
</body>
</html>

上面的隱藏 input 是為了在登入後能夠回到之前的網頁。
如果 refer 有資料,表示會員先到了需要登入的頁面。
如果 refer 沒有資料,在登入後轉址到 index.php。

接下來是 actionlogin.php:

程式碼:
<?php
require('config.php');

$email $_POST['email'];
$password $_POST['password'];
$refer $_POST['refer'];

if ($email == '' || $password == '')
{
    // No login information
    header('Location: login.php?refer='urlencode($_POST['refer']));
}
else
{
    // Authenticate user
    $con mysql_connect($db_host$db_user$db_pass);
    mysql_select_db($db_name$con);
    
    $query "SELECT userid, MD5(UNIX_TIMESTAMP() + userid + RAND(UNIX_TIMESTAMP()))
        guid FROM susers WHERE email = '$email' AND password = password('$password')";
        
    $result mysql_query($query$con)
    	or die ('Error in query');
    
    if (mysql_num_rows($result))
    {
        $row mysql_fetch_row($result);
        // Update the user record
        $query "UPDATE susers SET guid = '$row[1]' WHERE userid = $row[0]";
            
        mysql_query($query$con)
        	or die('Error in query');
        
        // Set the cookie and redirect
        // setcookie( string name [, string value [, int expire [, string path
        // [, string domain [, bool secure]]]]])
        // Setting cookie expire date, 6 hours from now
        $cookieexpiry = (time() + 21600);
        setcookie("session_id"$row[1], $cookieexpiry);

        if (empty($refer) || !$refer)
        {
            $refer 'index.php';
        }

        header('Location: '$refer);
    }
    else
    {
        // Not authenticated
        header('Location: login.php?refer='urlencode($refer));
    }
}
?>

首先檢查會員有沒有輸入帳號和密碼,如果沒有回到登入頁面,用最後面的 header 來控制。
接下來是到資料庫尋找會員的資料。
第一個資料庫的查詢會用 MD5() 函式來建立會員的 session id,然後檢查帳號跟密碼是否跟資料庫裡的相同。
如果相同,更新會員的 session id,這樣可以增加安全性。
所以會員的 session id 每登入一次就會不同。
接下來是建立一個 cookie,只要會員在六個小時內回到網頁就不需要重新登入。
後面的 if (empty($refer) || !$refer) 是為了轉址的功能。
如果有 refer 的值,會員在登入後會回到之前的網頁,沒有就回到 index.php。

再來是 incsession.php:

程式碼:
<?php
require('config.php');

// Check for a cookie, if none go to login page
if (!isset($_COOKIE['session_id']))
{
    header('Location: login.php?refer='urlencode(getenv('REQUEST_URI')));
}

// Try to find a match in the database
$guid $_COOKIE['session_id'];
$con mysql_connect($db_host$db_user$db_pass);
mysql_select_db($db_name$con);

$query "SELECT userid FROM susers WHERE guid = '$guid'";
$result mysql_query($query$con);

if (!mysql_num_rows($result))
{
    // No match for guid
header('Location: login.php?refer='urlencode(getenv('REQUEST_URI')));
}
?>

一開始會檢查有沒有 cookie,記得 actionlogin.php 裡面有設定 cookie 的 session_id。
如果沒有 cookie 表示會員還沒登入,然後轉址到 login.php,加上 refer 的網址。
接下來將 $guid 設為 cookie 裡面的 session_id,然後進行查詢的動作。
如果 mysql_num_rows($result) 裡面沒有東西,表示 cookie 裡的 session_id 跟資料庫裡的 guid 不一樣。
如果不一樣,進入登入頁面。

驗證的程式就到這裡,最後可以建立一個 test.php 的網頁:

程式碼:
<?php
include('incsession.php');

echo '這是會員區';
?>

當會員進入 test.php 的時候會先用 incsession.php 來檢查 cookie。
如果驗證不通過會進入登入頁面。如果成功會顯示 "這是會員區"。


靈感:http://www.devarticles.com/c/a/MySQL/Security-and-Sessions-in-PHP/

arrow
arrow
    創作者介紹
    創作者 James Wu 的頭像
    James Wu

    James's Privacy Corner

    James Wu 發表在 痞客邦 留言(32) 人氣()