2014-03-18 28 views
-2

所以我在html中做了如下的基本登錄表單。我明白現在缺少安全措施,但我只是希望它能夠首先登錄。然後,我將構建更高級的功能。Mysql登錄表

<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> 
<title>Jotorres Login Form</title> 
</head> 
<body> 
    <form method="post" action="login.php" > 
     <table border="1" > 
     <tr> 
      <td><label for="users_name">Username</label></td> 
      <td><input type="text" 
       name="users_name" id="users_name"></td> 
     </tr> 
     <tr> 
      <td><label for="users_pass">Password</label></td> 
      <td><input name="users_pass" 
       type="password" id="users_pass"></input></td> 
     </tr> 
     <tr> 
      <td><input type="submit" value="Submit"/> 
      <td><input type="reset" value="Reset"/> 
     </tr> 
    </table> 
</form> 
</body> 
</html> 

然後我打電話給login.php。我有一個名爲「tommytest」的RDS數據庫中的用戶,密碼是「tommytest」,但它不起作用。保持說不正確的用戶名或密碼。但如果我將表格留空並點擊提交,表示我已驗證。

<?php 

// Grab User submitted information 
$name = $_POST["users_name"]; 
$pass = $_POST["users_pass"]; 

// Connect to the database 
$con = mysql_connect("localhost","username","password"); 
// Make sure we connected succesfully 
if(! $con) 
{ 
    die('Connection Failed'.mysql_error()); 
} 

// Select the database to use 
mysql_select_db("ist421test",$con); 

$result = mysql_query("SELECT userName AND password FROM users_tbl WHERE userName = '$name'"); 

$row = mysql_fetch_array($result); 

if($row["userName"]==$name && $row["password"]==$pass) 
    echo"You are a validated user."; 
else 
    echo"Sorry, your credentials are not valid, Please try again."; 
?> 
+1

好吧,如果您將表單留空,則查詢結果將爲空白。 $ name和$ pass也是如此。所以當比較一個空的$ name到一個空的$ row ['userName']時,該等式爲TRUE。空白等於空白。我將在 – Rottingham

+0

之下放置一個更準確的方法使用'WHERE userName ='$ name'AND password ='$ pass'「);'或'WHERE userName ='$ name'」);'它需要用引號。 –

回答

1

首先,你可以考慮使用一個更安全的密碼存儲方法,如crypt()bcrypt()或PHP的password_hash()功能(已經被解決)。

此行是其中最大的問題是:(使用AND而不是爲您的列名的逗號)

"SELECT userName AND password FROM users_tbl WHERE userName = '$name'" 
       ^^^ 

然後,你沒有在WHERE userName = $name

使用引用$name

"SELECT username, password FROM users_tbl WHERE username = '$name' AND password='$pass'" 

這裏是基於mysqli_*的版本,其中PHP/SQL/HTML表單在一個文件中進行測試。

(測試)

<?php 
DEFINE ('DB_USER', 'xxx'); 
DEFINE ('DB_PASSWORD', 'xxx'); 
DEFINE ('DB_HOST', 'xxx'); 
DEFINE ('DB_NAME', 'xxx'); 

$mysqli = @mysqli_connect (DB_HOST, DB_USER, DB_PASSWORD, DB_NAME) 
OR die("could not connect"); 

if(isset($_POST['submit'])){ 
// Grab User submitted information 
$name = mysqli_real_escape_string($mysqli,$_POST["users_name"]); 
$pass = mysqli_real_escape_string($mysqli,$_POST["users_pass"]); 

$result = mysqli_query($mysqli,"SELECT username, password FROM users_tbl WHERE username = '$name' AND password='$pass'"); 

$row = mysqli_fetch_array($result); 

if($row["username"]==$name && $row["password"]==$pass){ 
    echo"You are a validated user."; 
    } 
else{ 
    echo"Sorry, your credentials are not valid, Please try again."; 
    } 

} // if(isset($_POST['submit'])){ 
?> 

<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> 
<title>Jotorres Login Form</title> 
</head> 
<body> 
    <form method="post" action="" > 
     <table border="1" > 
     <tr> 
      <td><label for="users_name">Username</label></td> 
      <td><input type="text" 
       name="users_name" id="users_name"></td> 
     </tr> 
     <tr> 
      <td><label for="users_pass">Password</label></td> 
      <td><input name="users_pass" type="password" id="users_pass"></input></td> 
     </tr> 
     <tr> 
      <td><input type="submit" name="submit" value="Submit"/> 
      <td><input type="reset" value="Reset"/> 
     </tr> 
    </table> 
</form> 
</body> 
</html> 

腳註:

考慮使用mysqli_*功能與prepared statementsPDOmysql_*功能被取消,並將從未來PHP版本刪除。

參見: crypt()documentation on bcrypt() on SO,和PHP的password_hash()功能。

+1

謝謝。這對我來說非常好。我知道我需要更新我的方法,只是我正在研究的一個簡單的項目。 – h3tr1ck

+0

@JustinHetrick不客氣,很高興幫助賈斯汀。 –

2
  1. 你們不守存儲安全的密碼。哈希+鹽需要
  2. 看看你的查詢,你是不是檢查
  3. 你應該閱讀有關SQL Injections
  4. mysql_ *已被棄用的用戶名和密碼,只有用戶名的組合。使用PDO或mysqli

現在,有什麼可能是錯誤的? 嘗試打印mysql_error()進行調試。現在

SELECT username,password FROM users_tbl WHERE username='username' AND PASSWORD='password'

,如果一行此查詢結果,該組合是正確的: mysql_num_rows()會給你的行數。

再次檢查PDO或Mysqli。

祝你好運。

+0

您的信息基本正確。我建議OP在WHERE子句中提供密碼和用戶名,就好像他們正在使用適當的哈希算法(如使用'password_hash()'創建的哈希算法)一樣,他們將無法生成匹配的密碼直到他們真正從數據庫獲取密碼/鹽爲止。在行返回後,他們必須驗證密碼作爲第二步。 –

+0

你是對的。我只想指出他試圖完成的查詢的樣子。 – msfoster

+0

想提一下,在WHERE子句中使用用戶名和密碼在這裏可以正常工作,因爲OP不是醃製或哈希。只是不好的做法。 – Nazca

3

所以,你有一系列的問題在這裏:

  • 您正在使用的是過時mysql_*功能。您應該考慮使用mysqliPDO
  • 你完全沒有辦法阻止SQL注入。您應該在SO中快速搜索SQL注入以瞭解如何解決此問題。
  • 當您應該散列密碼時,您正在使用明文密碼。您應該查看PHP文檔中的password_hash()password_verify()函數,以瞭解如何正確地哈希您的密碼。
  • 您尚未在SQL中使用單引號括起$name值。並且您沒有正確指定選擇字段(如SELECT userName, password ...)。此外,您沒有處理由您的查詢導致的任何錯誤,或者您會看到這一點。這實際上是您的代碼無法按預期工作的根本原因。您應該始終檢查任何DB函數調用的結果,以確保您在執行任何操作之前獲得預期結果。
  • 你沒有做任何事情來檢查表單值是否被實際輸入。這與上面提到的錯誤查詢結果以及使用寬鬆比較的事實一樣,在未輸入任何值時會爲您提供經過驗證的用戶文本。如果您有空的POST字段(對於任何必填字段),您甚至不應該對數據庫進行查詢。
  • 您也有一個跨站請求僞造(CSRF)漏洞。所以一旦你找到了基本的登錄功能,你可能想研究如何使用會話令牌來緩解這種風險。

我不是故意用一堆不特定回答你的問題的物品壓倒你。很顯然,您處於學習模式,所以我只想確保您對代碼目前超出簡單SQL語法問題的其他一些問題有很好的指導。希望您可以利用這些信息來幫助您更好地瞭解當您開始在Web應用程序中使用用戶登錄時需要考慮的問題。

0

除了跳躍的箍環之外,我會做類似的事情,即使這很容易出現SQL注入,我會在後面討論這個。

SELECT COUNT(*) FROM `users_tbl` WHERE `userName` = '$name' AND `password` = '$pass' 

所以,你將有此

$result = mysql_query("SELECT COUNT(*) 
    FROM `users_tbl` 
    WHERE `userName` = '$name' AND `password` = '$pass'"); 

if (!$result || mysql_num_rows($result) <= 0) { 
    // NO user found! 
} else { 
    // User found and password matches 
} 

這並不完全與SQL合作的一種安全的方式 - 因爲你是直接injecting值,用戶類型,正確的數據庫查詢。黑客可以輸入DROP TABLE users_tbl作爲他的用戶名,並可能會清空數據庫。

最重要的是,您正在使用從PHP中完全刪除的不推薦使用的mysql_方法 - 因此,當您查看有關這些方法的任何聯機文檔時,這是一個大紅色的框。

http://us2.php.net/manual/en/function.mysql-query.php

我希望這個答案可以幫助您瞭解查詢的問題,和一個小錯誤檢查,但進展之前,你應該幾個小時投入到對現代mysqliPDO方法迎頭趕上。

+1

請注意,如果OP使用正確哈希密碼(即隨機鹽),他們將無法使用WHERE子句中的密碼值執行查詢。他們必須從查詢中檢索密碼並進行驗證。 –

+0

@MikeBrant呃Mike,我完全同意你的觀點 - 但這遠遠超出了OP,你不覺得嗎?在他正確地醃製密碼以及它們的存儲方式之前,他有一些障礙需要跳躍。我甚至不會在最基本的項目中使用這樣的查詢,而只是簡單地說明爲什麼以及如何查看錯誤所在。 – Rottingham

+0

是和不是。這顯然超出了他們對如何處理數據庫登錄操作的理解。這就是說,如果你打算提供建議,我覺得你應該提供建議,讓用戶朝着正確的方向前進。在查詢中同時使用用戶名和密碼不會將它們向正確的方向移動。所有其他的點都非常好。 –

0

您在查詢中沒有正確檢索「密碼」,因此始終爲空$ row ['password'],只是一個空值將被驗證。 改變您的查詢像

SELECT userName , password FROM users_tbl WHERE userName = '$name'