使用salted密码登录用户的小型查询



我有类似的代码点火器模型

<?php
class Model_Login extends CI_Model{
function __construct(){
parent::__construct();
}
public function login_submit($arrayData){
extract($arrayData);
$username=clean($txtusername);
$password=clean($txtpassword);
//first get salt for the respective user.
$getsalt=$this->db->query("SELECT PASSWORD_SALT FROM USER_INFOS WHERE USER_NNAME=?",array($username))->row();
$salt=$getsalt->PASSWORD_SALT;
$password=sha1($salt.$password);
$query=$this->db->query("SELECT * FROM USER_INFOS WHERE STATUS='Y' AND USER_NNAME=? AND USER_PASSWORD=?",array($username,$password));
if($query->num_rows>0){
$row=$query->row();
// login successfull create session
$this->session->set_userdata('USER_ID', $row->USER_ID);
$this->session->set_userdata('USER_FULL_NAME', $row->USER_ENAME);
return "success";
}else{
return "Invalid username and/or password.";
}


}
}
?>

其中,PASSWORD_SALT是一个数据库字段,它包含使用hash函数散列的128个字符长的随机(对于每个用户)SALT。

如果USERNAME是唯一的,则该代码可以完美工作。但我试着想想客户可能会问用户名不应该是唯一的。如果用户名不是唯一的,它总是选择第一行,除了一个拥有相同用户名的人之外,所有人都将无法登录,即使他们提供了有效的用户名和密码。

在这种情况下,有什么更好的解决方案?

编辑

我知道让USERNAME不是唯一的是个坏主意。但在我们国家,有几个网站的用户名不是唯一的(或者在某些情况下用户名甚至是可预测的)。例如,我在银行的某个分行有一个账户,其分行代码为032,我的名字是John Smith,那么访问他们的电子银行账户的用户名将是032JOHNS,该分行中可能有不止一个John Smith最终拥有相同的用户名。要登录他们的ebanking系统,我只需要提供这个用户名和密码。

感谢

如果用户名不是唯一的,那么唯一标识用户的是什么

它必须是用户在登录时提供的,不能是用户名和密码的组合,因为不能保证两个用户不会选择相同的密码。

因此,如果用户名不是唯一的,那么其他的东西必须是唯一的(或者与用户名组合是唯一的)。例如,如果他们通过自定义域进行某种多租户操作,那么它就是域。

但是您不能有非唯一的用户名,并且期望密码来确定正确的用户。

(附带说明,你可以,但你不应该-我碰巧能够使用相同的电子邮件地址登录两个不同的亚马逊帐户,但密码不同。我想知道如果我更改了一个密码以匹配另一个密码会发生什么,但我太看重我的帐户了,无法尝试。)

如果你真的必须有非唯一的用户名,你可以用用户名循环所有用户,并检查每个用户的密码,即如果3个用户的用户名是foobar,而第一个密码检查失败,则检查第二个,依此类推。

(注意:我强烈建议不要这样做。如果用户名不能唯一,请使用电子邮件地址作为唯一标识符/登录)。

而不是这个:

$getsalt=$this->db->query("SELECT PASSWORD_SALT FROM USER_INFOS WHERE USER_NNAME=?",array($username))->row();
$salt=$getsalt->PASSWORD_SALT;
$password=sha1($salt.$password);
$query=$this->db->query("SELECT * FROM USER_INFOS WHERE STATUS='Y' AND USER_NNAME=? AND USER_PASSWORD=?",array($username,$password));

使用这样的东西:

$query=$this->db->query("SELECT * FROM USER_INFOS WHERE STATUS='Y' AND USER_NNAME=? AND USER_PASSWORD=SHA1(CONCAT(PASSWORD_SALT,?))",array($username,$password));

最新更新