「 记住我」功能的实现

分享 jsyzchen ⋅ 于 2017-06-09 18:28:23 ⋅ 2772 阅读

最近发现维护的CoffeePHP社区关闭了网页之后再次进入的时候需要再次登录,所以想要做一个「 记住我」的功能。

上网上查了一下,很多是直接把用户名和加密过的密码放到cookie里,然后验证用户名和密码与数据库里的是否相同,这样的话,功能是可以实现,但安全性就不敢苟同了。 然后参考Laravel的Auth,实现了一个安全性相对较高的「 记住我」功能。 基本思路就是使用用户标识(user_id或user_name)+登录标识(token),将他们存到用户浏览器的Cookie里,把token存入数据库,然后相比较是否相同即可。

1.在用户第一次登录的时候,将user_id和token存入cookie,token存入用户表。

//用户登录了,并且拿到了用户信息
$_SESSIONS['auth'] = $user; //使用session存储用户的信息
$rememberToken = md5(uniqid(rand(), TRUE));//使用不可逆算法生成token
$rememberMe = $userId . ':' . $rememberToken;
//对$rememberMe进行可逆的加密,PHP里有base64、mcrypt、openssl等,这里使用openssl
$pass = '1234';
$method = 'des-ede3';
$encryptRememberMe = openssl_encrypt($rememberMe, $method, $pass); 
setcookie('remember_me', $encryptRememberMe,time() + 15 * 86400 );//将加密过的字符串放入cookie,并设置超时时间,建议不要超过一个月

2.用户每次打开网站时验证登录状态

// 获取cookie
$rememberMeCookie = $_COOKIE["remember_me"];
if (!isset($_SESSION['auth']) && $rememberMeCookie) {
    // 解密获取cookie真正的值
    $pass = '1234';
    $method = 'des-ede3';
    $rememberMe = openssl_decrypt($rememberMe, $method, $pass); 
    list($userId, $rememberToken) = explode(':', $rememberMe);

   //根据用户id从数据库获取用户信息,记得要对$rememberMe进行防sql注入,以防别人猜出存入cookie值的加密算法,假设用户信息为$user的数组

    if (!empty($user) && $user['remember_token'] === $rememberToken) {//比较token是否相同
        //设置用户的session
       $SESSIONS['auth'] = $user;
    }
}

3.用户退出登录时记得删除cookie

//删除cookie
setcookie('remember_me',  '', time() - 3600 );
//再删除session
unset($_SESSION['auth']);
session_destroy();

至此就完成了「 记住我」的功能,cookie使用了可逆的加密,就算被别人破解了,后面还会去验证token是否与数据库里面的一致,这样安全性相对而言就高一些了。

本帖已被设为精华帖!
回复数量: 0
    暂无评论~~
    • 请注意单词拼写,以及中英文排版,参考此页
    • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`, 更多语法请见这里 Markdown 语法
    • 支持Emoji表情,在输入的时候只需要 ":" 就可以自动提示了
    • 上传图片, 支持拖拽和剪切板黏贴上传, 格式限制 - jpg, png, gif
    • 发布框支持本地存储功能,会在内容变更时保存,「提交」按钮点击时清空
    Ctrl+Enter