轉錄自 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/

在來將下面的資料輸入到 login.php: 再AGAIN 有錯字 哈哈哈!!! 我也在寫會員系統啦~~
被發現了>///< 這種寫法好久沒用了 0.0 現在都改用 PDO 方式,或是使用 Framework(CI)
我們公司也用CI 我剛開始學 交流一下!!!!
好呀,不過要等到手邊的案子告一段落,還要忙好一陣子 (Q.Q)
那個。。。如何下載PHP?
PHP 是程式語言不用下載也QQ 如果是問 IDE 那用 Notepad ++ 就很好用了
您好, 不好意思我是php的新手 想請問一下guid所代表的意思是什麼呢
Guid 只是欄位名稱,這裡是當主鍵用(Primary Key)
轉指後面那好像漏了一些東西
感謝指正,不過是漏了那一段呢?
請問板主~ 請問裡面提到的index.php 是要自己另外寫一個index.php嗎??
是的,可以自己寫也可以置換成想到導入的頁面唷
請問版主 我要先在SQL上建立的資料表要什麼欄位..
文章上面提到的 CREATE TABLE susers 那一段就是在建立資料表和欄位了唷
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 ) 輸入到語法執行對吧~ 可是她都一直錯誤QQ
這是 MySQL 的語法,使用不同的資料庫要做轉換唷,而且 MySQL 5.X 版之後預設也不是使用 MyISAM 也要跟著調整
版大您好,我把妳程式碼都RUN過一遍,但是輸入密碼成功並沒有跳轉頁面,只有網址後面變成這樣login.php?%20refer=index.php,可以請教一下是發生什麼問題了嗎?
瀏覽器版本是什麼?refer就我所知還沒有不支援的瀏覽器也 0.0
感謝大大的文章,很好用,但是請問如何添加登出功能呢?多謝了!
唔..只要添加一個按鈕,先執行session_destroy()及利用setcookie 將使用者的 cookies 變更為您想設定的內容,如 logout,接下來再切換您的首頁或想導入的頁面就可以嚕
不好意思, 我是新手, 請問大大一個簡單的問題, 這樣有心人是否去下載 config.php就可以知道SQL的帳號和密碼了? 這樣會有風險嗎?
是的,所以路徑要注意,別放在太容易被猜到的地方。也可以設定可以存取資料庫的 IP 位址,來增加保安。
謝謝大大迅速的回覆, 小弟太菜了, 無法完全理解, 請大大撥冗指導一下. 1. 我們會在別的檔案用require來取得config.php, 這樣路徑不是還是會被發現? 該怎麼做隱藏比較好?? 2. "設定可以存取資料庫的 IP 位址" : 不是很清楚, 能請大大幫忙解釋一下嗎? 感謝~~
1. 只要伺服器設定沒有問題,檔案內容是不會被看到的唷,只會看到瀏覽器解析的內容(就像在一般頁面中檢視原始碼);但若是透過 FTP 或其它方式取得檔案內容的話就沒辦法避免內容被看到了。 2. 不同的資料庫有不同的設定方式,以 MySQL 為例,在建立帳號時可以設定該帳號可以存取的 IP 為何,如 127.0.0.1
拜託您求求您,能否解決我的問題, ------------------------------------------------- 我們現在有用DREAMWEAVER做的網站,語法是HTML 和獨立的會員系統,PHP 和獨立的留言板 請問我要如何把這三個東西串連在一起 會員登入後回網站可以顯示,歡迎***(會員名稱) 到留言板留言後會自動顯示留言人的名字(會員名稱) --------------------------------------------- 請問您能否告訴我該怎麼做,能否告訴我詳細的步驟,拜託您~~~~~~
1. 登入後將會員資料寫入 session 或 cookies 2. 在各系統中將結果印出即可 if (loginsuccess) { $_SESSION["username"] = "王小明" } 在需要顯示的地方 echo $_SESSION["username"]; 即可
請問一下,我網頁建立好了,如果從LOGIN.php登入 成功會進去index,失敗會留在原地,但我要問的問題是 我在index.php一開始加入了 想防止使用者直接使用網址進去,不登入,結果發現會有錯誤 是在 if (!isset($_COOKIE['session_id'])) { header('Location:login.php?refer='. urlencode(getenv('REQUEST_URI'))); } 還有 if (!mysql_num_rows($result)) { header('Location:login.php?refer='. urlencode(getenv('REQUEST_URI'))); } 的地方出錯 我這網頁是建立在一個HR資料夾底下,該從何處修改呢?謝謝
呃...錯誤訊息是什麼呢?login.php也是在HR資料夾底下嗎? 可以直接用header('Location:login.php');試看看
是顯示 Warning: Cannot modify header information - headers already sent by (output started at D:\AppServ\www\hr\HRindex.php:9) in D:\AppServ\www\hr\incsession.php on line 7 Warning: Cannot modify header information - headers already sent by (output started at D:\AppServ\www\hr\HRindex.php:9) in D:\AppServ\www\hr\incsession.php on line 21 line7 和21是 header('Location:login.php?refer='. urlencode(getenv('REQUEST_URI'))); 如果改成header('Location:login.php') 還是不行 login.php也在HR資料夾底下
看起來是語法順序問題唷,header要放在html的head之前,或是換個寫法 利用 javascript 來轉址而不要使用 php 的 header
你好,我解決了 PHP.INI裡面的output_buffering改成On就好了 感謝唷!!
恭禧:)
*****
*****
我帳號登入後網頁跑出Error in query,這是什麼問題??
看字面上的意思是 SQL 語法錯誤
看不懂這是甚麼意思 mysqli_select_db() expects parameter 1 to be mysqli 那幾行是這樣寫的 $con = mysqli_connect($db_host, $db_user, $db_pass); mysqli_select_db($db_name, $con); $query = 'SELECT userid, MD5(UNIX_TIMESTAMP() + userid + RAND(UNIX_TIMESTAMP())) guid FROM member_list WHERE email = "'.$email.'" AND password = password("'.$password.'")'; $result = mysqli_query($query, $con) or die ('Error in query');
您可能把mysql和mysqli搞混了唷 http://php.net/manual/en/function.mysqli-connect.php mysqli要傳入的參數和mysql是不一樣的
感謝教學~ 講的滿清楚的 但2016-07-21 16:51
因為版面的問題被切掉了,完整內容是底下這樣: <input type="hidden" name="refer" value="<?php echo (isset($_GET['refer'])) ? $_GET['refer'] : 'index.php'; ?>"> 主鍵是 GUID,它是資料表內的唯一值,不過以這個 table 來說 ID 當主鍵也是可行的
一直出現Error in query,是有寫錯嗎?資料庫要建那些欄位?
感覺不是少欄位是SQL語法出錯也,注意單引號和雙引號唷
有沒有示範?
呃...內容就是完整範例呀
請問.....
$db_host 是指 mysql 資料庫所在位置,如果是同一台主機就是 localhost,不同台主機就填入資料庫所在IP 位置。 $db_user 是使用者名稱沒錯。 $db_pass 是密碼沒錯。 $db_name 是資料庫名稱,table 名字一般會寫在 php code 裡頭。
PHP Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in /home/tiffinet/public_html/actionlogin.php on line 24 PHP Warning: mysql_connect(): Unknown MySQL server host 'tiffinet_member' (2) in /home/tiffinet/public_html/actionlogin.php on line 24 PHP Warning: mysql_select_db() expects parameter 2 to be resource, boolean given in /home/tiffinet/public_html/actionlogin.php on line 25 PHP Warning: mysql_query() expects parameter 2 to be resource, boolean given in /home/tiffinet/public_html/actionlogin.php on line 30 求教~~
這段的意思是說 mysql_connect 是比較舊的原件不建議使用,請改用 mysqli 或是 PDO,我後來都改用 PDO 了(我覺得比較方便和安全,效能也比較好) 剩下的是指你的連線資訊填寫錯誤
請教大師~怎麼 ~多加個使用期限~ 例如:我做了一個軟體~利用mysql做登陸系統~ 付費會員可使用30天~帳號開通後使用30天~ 30天到期後~會員無法再登入使用~ 另外有辦法在~會員登入後顯示剩餘天數嗎? 然後是 ~ 管理員可以看到每位會員剩餘天數嗎? 那舊會員再付費續用~再增加30天使用期~怎麼設定呢? 麻煩你指教了~謝謝
在帳號密碼的資料表紀錄到期日,用到期日減現在時間就知道剩餘時間嚕。
請問~如果要禁止重複登入該怎麼寫呢~ 例如:同一個帳號 第2個登入後第1個會被踢掉~ 謝謝
1. 在紀錄帳號密碼的資料表裡多存一欄登入狀態,如果已經成功登錄在驗證時就禁止登入。 2. 頁面切換或是有 POST 動作時去讀取那個欄位(是否已登入成功或紀錄登入次數之類的),如果登入次數大於 1,就把 Session 清空。
哈摟版主 可以留個line的聯絡資訊 我想託您幫我製作個登入頁面 可以私下報價嗎? 我的賴 ax307141
請問一下版主.. 假設我的網頁名稱是1.php 我在登入之後要連到1.php需要改哪裡.. 我都改不出來
if (empty($refer) || !$refer) { $refer = '1.php'; } header('Location: '. $refer);
請問登入輸入完帳號密碼跳到出現ERROR 404 要怎麼解決?
<form action="actionlogin.php" method="POST"> actionlogin.php 是否存在? test.php 是否存在?
james大大,沒有登出頁><
logout 只需要把Session和cookies清空即可達成唷
感謝版大提供分享,讓我在自己的網站實作成功,謝謝! 另一方面,想請問您,在業界一般來說是不是利用 MD5 就夠了? 還是說都已改用 RSA?
在業界一般來說MD5或SHA1還是比較廣泛的使用,RSA會用在比較特殊的地方,如檔案加密之類的。單純以密碼這塊來說是不需要用到RSA的唷