2012-01-28 71 views
1

我在php中使用preg_match_all來檢查用戶名和密碼中的字符,然後將它們添加到數據庫中,但似乎無法讓它按照我想要的方式工作。以下是我現在所擁有的:PHP preg_match_all模式

preg_match_all(USERNAME_PATTERN,$username,$usernameMatches); 
preg_match_all(PASSWORD_PATTERN,$password,$passwordMatches); 

這裏有圖案,定義爲常量:

/*Username and Password Patterns*/ 
define("USERNAME_PATTERN","[-*_a-z0-9A-Z.]"); 
define("PASSWORD_PATTERN","[_a-z0-9A-Z]"); 

我不知道什麼是錯的。它假設檢查用戶名是否具有a-z,A-Z,0-9,短劃線,星號,下劃線和句點之外的任何內容。密碼與用戶名相同。

這裏是我用來檢查代碼:

if ($usernameMatches == 0){ 
echo("Bad characters in username<br />"); 
} 

的密碼是一樣的。

+2

爲什麼限制密碼?無論如何,你只存儲它們的哈希值。 – fuxia 2012-01-28 15:14:16

回答

3

有你的代碼的幾個問題。

  1. 您的regexes只匹配一個字符。
  2. 你的正則表達式中沒有開始和結束的錨點。
  3. 請確保在調用preg_match_all()
  4. 你的正則表達式應該用/(或其他有效字符)包圍之前實例化匹配陣列。
  5. 通過檢查數組是否爲空來檢查不匹配,而不是通過檢查它是否等於零來檢查。 PHP中有許多類型/值檢查陷阱,最好避免它們。

試試這個:

/*Username and Password Patterns*/ 
define("USERNAME_PATTERN","/^[-*_a-z0-9A-Z.]+$/"); 
define("PASSWORD_PATTERN","/^[_a-z0-9A-Z]+$/"); 

$usernameMatches = array(); 
$passwordMatches = array(); 

preg_match_all(USERNAME_PATTERN,$username,$usernameMatches); 
preg_match_all(PASSWORD_PATTERN,$password,$passwordMatches); 

if (empty($usernameMatches)){ 
    echo("Bad characters in username<br />"); 
} 

if (empty($passwordMatches)){ 
    echo("Bad characters in password<br />"); 
} 

BTW:你的代碼可以通過簡單地使用preg_match()代替preg_match_all()簡化。像這樣的東西應該工作以及你的代碼:

/*Username and Password Patterns*/ 
define("USERNAME_PATTERN","/^[-*_a-z0-9A-Z.]+$/"); 
define("PASSWORD_PATTERN","/^[_a-z0-9A-Z]+$/"); 

if (!preg_match(USERNAME_PATTERN, $username)) { 
    echo("Bad characters in username<br />"); 
} 
if (!preg_match(PASSWORD_PATTERN, $password)) { 
    echo("Bad characters in password<br />"); 
} 
+0

目前無法測試,但是您是否還需要轉義「。」,「*」和「 - 」? – 2012-01-28 15:19:42

+1

@Joachim Isaksson:不。點和星不是元字符,當他們在_角色class_中時。如果減號位於第一個或最後一個位置,則減號不是字符類中的範圍元字符。 – Asaph 2012-01-28 15:26:14

+0

謝謝你,我已經改變爲preg_match,並且正在使用你的方式,因爲它確實更容易做到。 – legobear154 2012-01-28 15:33:13

2

使用此:

define("USERNAME_PATTERN","/^[-*_a-z0-9A-Z.]+$/"); 
define("PASSWORD_PATTERN","/^[_a-z0-9A-Z]+$/"); 

目前,您只允許單字符的用戶名和密碼。你也忘記了用/(或其他字符)封裝正則表達式。 (誠​​然,這是針對PHP和其他一些語言的。)我還添加了^和$,以便整個輸入字符串相匹配。

順便說一句,爲什麼麻煩檢查密碼?只是需要一定的最小長度,例如(但不是在所有檢查安全):

define("PASSWORD_PATTERN","/^.{6,}$/"); 

另外,我不知道爲什麼你使用preg_match_all。一個preg_match應該做的,以及,可能是更容易使用:

if (!preg_match(USERNAME_PATTERN, $username) { 
    echo("Bad characters in username<br />"); 
} 
+0

好的,謝謝。我可能只會限制密碼的長度。 – legobear154 2012-01-28 15:16:26

+0

爲什麼限制長度?希望你不會以明文存儲密碼;你應該計算你存儲在數據庫中的密碼的散列。即便如此,這被認爲是不安全的。鹽漬哈希是要走的路。 – robert 2012-01-28 15:19:10

+0

我正在加密密碼。我也在醃製它。當我第一次這樣做的時候,我真的不知道我腦子裏經歷了什麼。感謝大家的幫助!任何人都可以點我一個很好的網站,學習如何創建主要用於PHP的模式? – legobear154 2012-01-28 15:25:41

1

不知道什麼是錯的。它假設檢查用戶名是否具有a-z,A-Z,0-9,短劃線,星號,下劃線和句點之外的任何內容。密碼與用戶名相同。

如果傳遞的用戶名/密碼有效,您應該檢查。你需要這種模式。 /^[\-\*\w\d\.]{6,12}$/,這裏最小和最大長度分別是6和12。

define('PATTERN', '/^[\-\*\w\d\.]+$/'); 
if(preg_match(PATTERN, $username)){ 
// username is correct 
} else { 
// username is wrong. 
} 

相同的密碼。

1

在回答之前,我只想說通過問這個問題,我懷疑你是直接將密碼保存爲明文。這不是一個好的解決方案,因爲它暴露了你的用戶密碼。有關圍繞here的討論,並舉例說明如何以更安全的方式實現此目的。

作爲一個額外的好處,無效字符(在密碼中)的問題不會成爲大多數情況下的問題,除非您正在處理一些遺留系統。原因是你不會存儲實際的密碼,但只是生成的散列

回到你的問題。我喜歡的另一種選擇是檢查任何無效字符的偏見。通過將^添加到字符列表中,您將匹配任何字符其他比列表。

define("USERNAME_PATTERN","/[^*_a-z0-9A-Z.-]/"); 
if(preg_match(USERNAME_PATTERN, $username)) 
    echo 'Bad characters in username';