2015-09-05 65 views
3

我正在学习PHP,并将其作为一个项目开始构建社交网络。我确实创建了注册表单和登录表单,并且可以将用户添加到我的数据库中。我也散列他们的密码。这是一个简单的网站和正在进行的工作,因此存在很多安全漏洞。如何使用password_verify()从数据库中检索密码?

我的问题是与登录文件,我似乎无法匹配用户与他给我的密码。为了验证用户密码,我使用了password_verify()函数,但它似乎并不正确。

这里是我的代码:

注册

<?php 
//signUp.php 
//Here is where I add a user in my database 
//I validate the input, confirm that the password is written like it should be 
//check if a user with the same username exists in the database 
//if all checks out I will add the user in the database 
    //and redirect the user to his profile 
    require_once 'login.php'; 
    require_once 'helperFunctions.php'; 

$conn = new mysqli($servername, $username, $password, $database); 

if(!$conn) 
    die("Connection failed:" . mysqli_connect_error()); 

$myUsername = $_POST['Name']; 
$myPassword = $_POST['Password']; 
$myConfirm = $_POST['conPass']; 

sanitize($conn, $myUsername); 
sanitize($conn, $myPassword); 

//check if the two passwords are the same 

if($myPassword != $myConfirm){ 
    print "Your passwords don't match"; 
    header("refresh: 5; index.html"); 
} else { 
    //check if username already exists in database 
    $query = "SELECT * FROM members WHERE Username='$myUsername'"; 
    $result = mysqli_query($conn, $query); 

    $count = mysqli_num_rows($result); 

    if($count == 0){ 
     //hash password 
     $hashedPass = password_hash("$myPassword", PASSWORD_DEFAULT); 

     //username doesn't exist in database 
     //add user with the hashed password 
     $query ="INSERT INTO members (Username, Password) VALUES  ('{$myUsername}', '{$hashedPass}')"; 
     $result = mysqli_query($conn, $query); 

     if(!$result) 
      die("Invalid query: " . mysqli_error()); 
     else{ 
      print "You are now a member or The Social Network"; 
      header("refresh: 5; login_success.php"); 
     } 

    } else { 
     print "Username already exists"; 
     header("refresh: 5; index.html"); 
    } 

} 
?> 

登录

<?php 
//checkLogin.php 
//Here is where I authenticate my users and if successfull I will show them their profile 
require_once 'login.php'; 
require_once 'helperFunctions.php'; 

$conn = new mysqli($servername, $username, $password, $database); 

if(!$conn) 
    die("Connection failed:" . mysqli_connect_error()); 

//Values from form 
$myUsername = $_POST['Name']; 
$myPassword = $_POST['Password']; 

//sanitize input 
sanitize($conn, $myUsername); 
sanitize($conn, $myPassword); 

$query = "SELECT * FROM members WHERE Username='$myUsername'"; 
$result = mysqli_query($conn, $query); 
$count = mysqli_num_rows($result); 

if($count == 1){ 
    $row = mysqli_fetch_array($result, MYSQLI_ASSOC); 
    print "hashedPass = ${row['Password']}"; 
    print "myPassword: " . $myPassword; 
    if(password_verify($myPassword, $row['Password'])){ 
     print "Password match"; 
    } else 
     print "The username or password do not match"; 
} 
?> 

消毒功能

function sanitize($conn, $val){ 
    $val = stripslashes($val); 
    $val = mysqli_real_escape_string($conn, $val); 
} 

通过运行程序print "hashedPass = ${row['Password']}";打印出散列的密码,这与我在我的数据库中使用的密码相同,但由于某种原因,我在此之后重定向到print "The username or password do not match";声明。

+0

你在做什么来'$ myPassword'在'的sanitize()'函数?告诉我们该代码 – RiggsFolly

+0

你正在为SQL注入开放。如果有人说他们的用户名是“',该怎么办? DROP TABLE members;'你的SQL语句现在评估为'SELECT * FROM members WHERE Username =''; DROP TABLE成员;''。你需要使用像[PDO](http://php.net/manual/en/book.pdo.php)。 (我知道你说有安全漏洞,但这是一个很大的,所以我忍不住提起它) – bytesized

+0

@RiggsFolly我添加了sanitize函数的代码 – captain

回答

4

评论拉,从已删除的答案采取:

“我记得当我第一次创造了我用CHAR(10),而散列密码需要更多字符密码的数据库。”

所以这里的全能答案是,你的密码栏是50个字符短。

password_hash()创建一个60个字符的字符串。

该手册指出最好使用VARCHAR并且长度为255以适应未来的变化。

解决现在这个样子,是一个新的开始登记了,然后用你目前正在使用的是什么重新登录。从手动

实施例:

<?php 
/** 
* We just want to hash our password using the current DEFAULT algorithm. 
* This is presently BCRYPT, and will produce a 60 character result. 
* 
* Beware that DEFAULT may change over time, so you would want to prepare 
* By allowing your storage to expand past 60 characters (255 would be good) 
*/ 
echo password_hash("rasmuslerdorf", PASSWORD_DEFAULT)."\n"; 
?> 

以上例程的输出类似的东西,以:

$ 2Y $ 10 $ .vGA1O9wmRjrwAVXD98HNOgsNpDczlqm3Jq7KnEd1rVAGv3Fykk1a

从手动

另外:

注意事项 使用PASSWORD_BCRYPT作为算法参数,将导致密码参数被截断为最多72个字符的长度。

PASSWORD_DEFAULT - 使用bcrypt算法(默认为PHP 5.5.0)。请注意,随着新的更强大的算法添加到PHP中,此常量将随时间而改变。出于这个原因,使用这个标识符的结果的长度会随着时间而改变。因此,建议将结果存储在可扩展超过60个字符的数据库列中(255个字符将是一个不错的选择)。

PASSWORD_BCRYPT - 使用CRYPT_BLOWFISH算法创建哈希。这将使用“$ 2y $”标识符产生标准的crypt()兼容散列。结果将始终为60个字符的字符串,或者失败时为FALSE。
支持的选项:

另一个评论/问题被删除的答案拉:

“?我可以更改,而不必删除我的表,并从一开始就开始了我的密码字段”

答案是肯定的。见这种问答& A于堆栈:

您也可以咨询:

旁注:你仍然需要重新输入新的哈希(旧)受影响的列。

另外,如前所述;你已经开放SQL注入。使用准备好的语句:

+0

这是正确的答案。对不起,迟到的回复,没有时间在问题上工作 – captain

+0

@captain无后顾之忧。我很高兴听到我能够帮助,*欢呼* –

相关问题