如何去管理php的用户名和密码(三)0+
35,656 views / 2011.12.15 / 7:07 下午
(接上文:http://71j.cn/archives/183)
用户传入数据的过滤
我们不能紧紧依靠mysql的过滤的机制,而需要对用户输入的变量进行非法字符过滤,防止DoS攻击和sql注入。
$user = get_post_var('user'); if(!preg_match('/^[a-zA-Z0-9_]{1,60}$/', $user)) fail('用户名不合法'); $pass = get_post_var('pass'); /* 好歹我们也应该节省点CPU和内存吧,哈哈 */ if (strlen($pass) > 72) fail('The supplied password is too long'); |
这一步很关键。在每个项目中,我们都有专门的类来处理$_POST和$_GET过来的数据,保障数据安全。
验证用户身份
一般开发过程中,从安全角度考虑,我们都不建议存储用户密码的明文,这是为什么呢?杜工卖个关子,读者自己思考吧。
创建新用户:
$hash = $hasher->HashPassword($pass); if (strlen($hash) < 20) fail('密码分配失败'); unset($hasher); ($stmt = $db->prepare('insert into users (user, pass) values (?, ?)')) || fail('MySQL prepare', $db->error); $stmt->bind_param('ss', $user, $hash) || fail('MySQL bind_param', $db->error); if (!$stmt->execute()) { if ($db->errno ===1062 /* ER_DUP_ENTRY */) fail('This username is already taken'); else fail('MySQL execute', $db->error); } |
验证用户身份:
($stmt = $db->prepare('select pass from users where user=?')) || fail('MySQL prepare', $db->error); $stmt->bind_param('s', $user) || fail('MySQL bind_param', $db->error); $stmt->execute() || fail('MySQL execute', $db->error); $stmt->bind_result($hash) || fail('MySQL bind_result', $db->error); if (!$stmt->fetch() && $db->errno) fail('MySQL fetch', $db->error); if ($hasher->CheckPassword($pass, $hash)) { $what= 'Authentication succeeded'; } else { $what = 'Authentication failed'; } unset($hasher); |
由此,验证过程完毕。非常安全。
修改密码
修改密码前一定要验证原来的密码是否正确:
if ($hasher->CheckPassword($pass, $hash)) { $what= 'Authentication succeeded'; } else { $what = 'Authentication failed'; $op = 'fail'; // Definitely not 'change' } |
随后进行密码规则判断,看是否符合要求,再进行update操作。
$newpass = get_post_var('newpass'); if(strlen($newpass) > 72) fail('The new password is too long'); $hash = $hasher->HashPassword($newpass); if(strlen($hash) < 20) fail('Failed to hash new password'); unset($hasher); ($stmt = $db->prepare('update users set pass=? where user=?')) || fail('MySQL prepare', $db->error); $stmt->bind_param('ss', $hash, $user) || fail('MySQL bind_param', $db->error); $stmt->execute() || fail('MySQL execute', $db->error); $what = 'Password changed'; |
这样,已经存在的用户密码就会被修改成功了。