实现下次自动登录,其实就是将用户名和密码保存到Cookie中,然后为Cookie设置一个较长的有效期,即使用户关闭浏览器,下次也能通过Cookie保持登录状态。在保存Cookie时,考虑到用户的密码安全,显然不能将密码明文存储,我们可以使用一种“密码加盐”的方式提高密码的安全性。
修改数据库中的用户表,在表中增加一个“salt”字段。
alter table `user` add `salt` char(32) not null after `password`;
2、修改register.php。修改用户注册的加密算法。
//用户名不存在,可以注册。
//生成密码盐
//md5(uniqid(microtime()))是生成固定位随机字符串的一种方式
$salt=md5(uniqid(microtime()));
//拼接密码盐,提升密码安全
$password=md5($salt.md5($password));
//拼接插入数据的SQL语句
$sql="insert into `user` (`username`,`password`,`salt`,`email`) values ('$username','$password','$salt','$email')";
3、修改login.php。
(1)修改用户登录的加密算法。
//根据用户名取出用户信息
$sql="select `id`,`password`,`salt` from `user` where `username`='$username'";
if($res=mysql_query($sql)){//执行sql,获得结果集;
$row=mysql_fetch_assoc($res);//处理结果集
$password=md5($row['salt'].md5($password));//以用户注册时密码加密的方式进行MD5运算
//判断密码是否正确
if($password==$row['password']){
......
}
}
(2)保存登录状态
//判断密码是否正确
if($password==$row['password']){
//判断用户是否勾选了“下次自动登录”
if(isset($_POST['auto_login']) && $_POST['auto_login']=='on'){
//将用户名和密码保存到Cookie,并对密码加密
$UserAgent=isset($_SERVER['HTTP_USER_AGENT'])?$_SERVER['HTTP_USER_AGENT']:'';
$password_cookie=md5($row['password'].md5($UserAgent.$row['salt']));
$cookie_expire=time()+2592000;//保存一个月(60*60*24*30)
setcookie('username',$username,$cookie_expire);//保存用户名
setcookie('password',$password_cookie,$cookie_expire);//保存密码
}
//登录成功,保存用户会话
......
}
(3)实现自动登录
//连接数据库,设置字符集,选择数据库
dbInt();
......
//当有表单提交时
......
//当Cookie中存在登录状态时
if(isset($_COOKIE['username']) && isset($_COOKIE['password'])){
//取出用户名和密码
$username=$_COOKIE['username'];
$password=$_COOKIE['password'];
//Cookie是来自浏览器的数据,可以被篡改,因此服务器接收后必须先验证数据的合法性
$username=mysql_real_escape_string($username);//对不安全的输入进行SQL转义
//根据用户名取出用户信息
$sql="select `id`,`password`,`salt` from `user` where `username`='$username'";
if($res=mysql_query($sql)){//执行sql,获得结果集;
$row=mysql_fetch_assoc($res);//处理结果集
//计算Cookie密码
$UserAgent=isset($_SERVER['HTTP_USER_AGENT'])?$_SERVER['HTTP_USER_AGENT']:'';
$password_cookie=md5($row['password'].md5($UserAgent.$row['salt']));
//验证Cookie密码
if($password==$password_cookie){
//登录成功,保存会话
......
}
}
}
4、修改user.php
//用户退出功能
if((isset($_GET['action']) && $_GET['action']=='logout')){
//清除Cookie数据
setcookie('username','',time()-1);
setcookie('password','',time()-1);
//清除SESSION数据
......
}
5、测试自动登录功能
注册一个新用户,在浏览器中访问login.php,输入用户名和密码并选中“下次自动登录”,登录成功后关闭浏览器。再次访问login.php,如果自动跳转到user.php,说明本功能已成功实现。
6、知识点
(1)提高Cookie的安全性
目前的主流浏览器都为Cookie提供了HttpOnly属性,该属性可以使Cookie只能通过HTTP协议访问,禁止JavaScript访问。
setcookie('password','123456',null,null,null,null,true);//传递了7个参数,null代表参数使用默认值,第7个参数将HttpOnly设置为true,这样就使password这个Cookie只能通过HTTP协议访问。
由于Session技术也使用了Cookie,为了使Cookie数据也具有HttpOnly属性,可以在php.ini中开启session.cookie_httponly选项。如果仅在脚本中临时设置,可以通过ini_set();函数临时修改php.ini的设置,该修改仅在脚本内有效。ini_set('session.cookie_httponly',1);
(2)输出缓冲(还不理解)
在PHP中,输出缓存(Output Buffer)是一种缓冲机制,它通过内存预先保存PHP脚本的输出内容,当缓存的数据量达到设定的大小时,再将数据传输到浏览器。
输出缓冲机制解决了当前内容输出后,再使用header()、setcookie()、session_star()等函数无法设置HTTP消息头的问题。
因为消息头必须在主体数据之前被发送,通过输出缓冲,可以使主体数据延缓到HTTP消息头的后面被发送。
输出缓冲在PHP中是默认开启的。在php.ini中,它的配置项为output_buffering=4096,表示输出缓冲的内存空间为4KB。
通过PHP的ob函数可以控制输出缓冲,常用代码如下:
//启动输出缓冲
ob_start();
//返回当前输出缓冲区的内容
ob_get_contents()
//向浏览器发送输出缓冲区的内容,并禁用输出缓冲
ob_end_flush();
//清空输出缓冲区的内容,不进行发送,并禁用输出缓冲
ob_end_clean();