将密码放入我的数据库后 (列密码是二进制(255)类型)
//let's say his username is on $username and password in $password
$password = "abc123";
$con = new PDO( DB_DSN, DB_USERNAME, DB_PASSWORD );
$con->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$con->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
$sql = "INSERT INTO users(username, password) VALUES(:usr,:psw)";
$stmt->bindValue( "usr", $username, PDO::PARAM_STR );
$newpsw = password_hash ( $password , PASSWORD_DEFAULT);
$stmt->bindValue( "psw", $newpsw, PDO::PARAM_STR );
$stmt->execute();
通过cmd我去数据库,我可以看到密码是这个
$2y$10$nDzlRwWfC9sTvVqv5f7G1eByHethRHjEWGwBOjkpoaq3y2Fb.LCC.
现在,当用户登录时,我成功地从数据库中检索了他的密码
//let's say his username is on $username and password in $password
$con = new PDO( DB_DSN, DB_USERNAME, DB_PASSWORD );
$con->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$con->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
$sql = "SELECT password FROM users WHERE username = :usr LIMIT 1";
$stmt = $con->prepare( $sql );
$stmt->bindValue( "usr", $username, PDO::PARAM_STR );
$stmt->execute();
$result = $stmt->fetch();
$psw_from_db = $result["password"]; //checked with echo and it's correct
如果我这样做
password_verify($password , $psw_from_db);
虽然我检查了$ password和$ psw_from_db,但它会返回false 并且他们内部有正确的价值。
如果我直接从数据库中复制密码并将其替换为$ psw_from_db,则会返回true
password_verify($password ,'$2y$10$nDzlRwWfC9sTvVqv5f7G1eByHethRHjEWGwBOjkpoaq3y2Fb.LCC.');
//'' have to be used, it won't work with ""
我现在正在寻找几个小时,但我还没有找到解决方案。
答案 0 :(得分:3)
根据BINARY datatype in MySQL的文档,您看到的答案似乎是\0
(空字符):
当存储
BINARY
值时,它们会用填充板右边填充 值到指定的长度。填充值为0x00
(零 字节)。值在插入时右边填充0x00
,没有尾随 select上删除了字节。所有字节在比较中都很重要, 包括ORDER BY和DISTINCT操作。0x00
个字节和空格 比较不同,0x00
<空间。
因此,当您从数据库中检索密码时,您实际上收到的长度为255的字符串(这就是我在my comment中要求var_dump
而不是echo
)的原因。在本地测试一些值,我得到了类似的东西:
string(255) "$2y$10$L5C66A5xFvf1YYAoWbnQDuRyveVOrnz1jfV/Eb0kT9UkZlWzCfK8a"
string(255) "$2y$10$EAkfkh8S1m66FWAX/KZYMeuhteDREL5B22cgLP0feKZ9.ydMgcgpa"
string(255) "$2y$10$Ll/272JbvIilDj74FAqVIeckWUGezqT926Z1LkVBZZSVwTaFUGOLe"
string(255) "$2y$10$fxvZv2ya0RncOksp09vqjekIWNmdEX9fEUahU6puSe8HqGcY51re6"
string(255) "$2y$10$f1xDu3fFnqMw.MEa4.93Tu3ouhr3kmXXbe41oTyy8xGTKaRbafQ8G"
string(255) "$2y$10$YhjBmNFjL7a8lj1Soyvdhe9GpfQ7SsX.dfkI0keQ0IgrkKIfQQjpC"
您可以使用trim
或使用BINARY(255)
归类将数据类型从BINARY(60)
更改为CHAR(60) BINARY
或CHAR(60)
,甚至更改为latin1
。 (bcrypt哈希值为59-60字节)。