绝大多数情况下,一款Web应用系统的用户认证机制,最常见的实现方式,就是自定义用户管理功能,该模块是内嵌在web应用中,随web应用一起发布出去的。然而,对于一些特殊的应用,尤其是基于linux服务器的应用软件,它们会经常使用linux本地的用户认证机制,来实现用户的认证功能。下面就来看一下在平时的开发过程中如何使用linux的本地用户认证机制。
首先,明白一点,linux系统中,真正的用户账号信息是保存在/etc/shadow文件中,而不是/etc/passwd文件。
模拟场景如下:
用户在打开的web登录界面上输入用户名和密码,提交后,后台判断该用户名和密码是否正确。
具体的实现步骤如下:
1.获取linux用户信息
通过以下命令,获取到某个指定用户的密码信息。
$sys_pwd= shell_exec('cat /etc/shadow|grep "user_name"| head -n 1|cut -d ":" -f2');
此处的user_name,就是用户在web登录界面上输入的用户名称。
返回的结果$sys_pwd如果为空,则表示该用户不存在,反之,将会返回类似如下的信息:
$6$Lof/n6en$HlVk8g5sFW9Ip.AiyxhIWJshyanWwKA6uFkj2gbRCBF09AFomDXcSVxYf4pm0vQOzw33tTa8YERe2hYIcJNqE.
可以看到,这个字符串被美元符号$分割成了3段,每一段的含义如下:
第一段:salt类型,可选值有:1, 2a, 5, 6,此处是6
第二段:salt干扰值,此处是Lof/n6en
第三段:真正的密码串,是linux利用crypt加密方式自动生成的
2.密码比对
将用户在web登录界面上输入的密码通过crypt加密后,检查该加密结果与步骤1中拿到的密码是否一致,如果一致,则匹配成功,反之,则说明用户输入的密码是错误的。
if ($sys_pwd) {
$result = explode('$', $sys_pwd);
$pwd = encrypt($password,$result[2],strval($result[1]));
if ($pwd == str_replace(chr(10), '', $result[3])) {
echo '用户认证成功';
} else {
echo '用户认证失败';
}
}
代码中的$password,表示用户在web登录界面上输入的密码。
附crypt函数如下:
/**
* 字符串加密
* @param string $str 待加密字符串
* @param string $salt salt干扰值
* @param string $salt_type salt类型,可选值有:1, 2a, 5, 6
* @return string
*/
function encrypt($str = null,$salt = null,$salt_type = null){
$result = '';
//密码所在列
$pwd_index = 0;
switch ($salt_type) {
case '1':
$pwd_index = 3;
if (CRYPT_MD5 == 1) {
$result = crypt($str,'$1$'.$salt.'$');
}
break;
case '2a':
$pwd_index = 3;
if (CRYPT_BLOWFISH == 1) {
$result = crypt($str,'$2a$09$'.$salt.'$');
}
break;
case '5':
$pwd_index = 4;
if (CRYPT_SHA256 == 1) {
$result = crypt($str,'$5$rounds=5000$'.$salt.'$');
}
break;
case '6':
$pwd_index = 4;
if (CRYPT_SHA512 == 1) {
$result = crypt($str,'$6$rounds=5000$'.$salt.'$');
}
break;
default:
$result = $str;
break;
}
if ($result) {
$rs = explode('$', $result);
return str_replace(chr(10), '', $rs[$pwd_index]);
}
return $result;
}