欢迎光临 Rick 's BLOG
日志首页  | C# .Net编程  | 原创作品  | 生活点滴  | C\C++相关  | 多媒体相关※ERMP  | VB相关  | 其它运维与编程  |  留言簿
IIS中如何实现nginx那样的反向代理功能 开启SSL证书,nginx配置http跳转https以及CodeIgniter 4系统配置注意事项
晴天  在php中实现安全的用户登录、Cookie中保存登录状态(remember me)
[ 发布日期:1年前 (2023-12-02) ]   [ 来自:本站原创 ] [分类:原创作品]
使用安全的方式实现用户登录,并在Cookie中保存登录状态,记住我(remember me)功能。

比较天真的实现方式:将登录凭证、权限信息等保存到Cookie中。
真的是很可怕,本站之前使用的老ASP博客系统就是这么实现的。
最终导致系统被黑,网站被挂马。。。。。

这次开发的新系统考虑到这种教训,采用了比较安全的实现方式。

1,在用户密码的存储和验证方面使用了安全性较高的实现方案。


 具体实现方式在之前的文章中有详细介绍。
a. 对密码强度进行要求。 参考  简单实现js密码强度检测,友好的html css样式提示 
密码要求至少8位,大小写字母数字标点符合至少包含三种。
保证密码的基本安全性。

b.  对密码采用安全的hash加密存储。参考 在PHP程序中实现安全的用户密码保存-加密存储和登录验证
密码安全存储是为了应对数据泄漏风险。


2,在登录时进行暴力破解预防


最基本的两项就是 验证码 和 密码试错次数限制。
验证码功能可以参考之前的文章 在CodeIgniter4中集成谷歌验证码 reCaptcha V2 

关于密码错误次数的限制,网上有一些天真的利用 Session 记录错误次数的实现代码。
那样是完全没有效果的。

错误次数可以在数据库中记录,也可以在Memcache,redis等缓存中记录。
CodeIgniter4有缓存模块,我们这里可以直接利用它自带的缓存模块实现
[复制到剪贴板]


/**
 * 判断是否超出了最大错误次数
 * 2小时内错误5次
 */ 
function password_CheckErrors($username):bool{
    
$key 'passErr_' $username ;
    
$data cache($key)?? 0;
   
    if(
$data >= 5)
        return 
true;
    return 
false;
}
/**
 * 记录错误次数
 */ 
function password_addErrors($username): int{
    
$key 'passErr_' $username ;
    
$data cache($key) ?? 0;    
    
$data++;
    
cache()->save($key$data7200);//2小时
    
return $data;
}
/**
 * 获取当前错误次数
 */ 
function password_getErrors($username):int{
    
$key 'passErr_' $username ;
    
$data cache($key)??0;
    
    return (int)
$data;
}
 



根据用户名来记录密码错误次数信息,在登录时先判断错误次数。次数超过时直接报错。
然后进行登录验证,密码失败时,调用辅助函数记录次数。


3,安全的使用Cookie保存登录状态


首先,绝对不能将用户凭证权限等信息保存到Cookie中。
我们可以在Cookie中保存一个没有实际意义token标识。同时将这个token标识,过期信息保存到数据库中和用户关联。
[复制到剪贴板]

/**
 * @param $length 生成的Token字符长度
 * @return 返回生成的Token字符串
 */ 
function password_generateToken(int $length 20): string{
    return 
bin2hex(random_bytes($length));
}
 



在用户登录成功后通过上面的辅助函数生成一个随机token。

在用户下次访问时直接获取token值,然后从数据库中查询是否有关联用户。
如果找到用户,先判断是否过期,然后实现自动登录,并从数据库中获取用户权限等信息。

如果考虑更严格安全一点,也可以在数据库中记录用户的IP地址,UserAgent等信息,要求完全匹配才给登录。


4,自动登录Token的注销


在用户进行密码修改后要主动从数据中删除token值,避免安全漏洞。

在用户 点击 退出登录 后,也要主动注销token值,同时注销Session。
这一点很重要,可以保证用户在公共场合登录帐号后能安全退出。
在用户退出后不会给Cookie劫持或者Session劫持攻击机会。


5,最后,敏感操作要重新验证用户密码


如用户修改密码、邮箱、绑定手机号等情况,需要重新验证用户,以保证安全。
引用通告地址 (0):
复制引用地址https://www.rickw.cn/trackback/285
复制引用地址https://www.rickw.cn/trackback/285/GBK
[ 分类:原创作品  | 查看:2415 ]

引用这个评论  rick 于 2023-12-03 12:50:49 发表评论: [置顶]
还有一个注意事项:
是否允许用户在多个设备同时保存登录状态
如果允许的话,数据库中就可以保存多个token。
如果不允许的话,就应该只保留一个token,每次登录保存时要记得查询删除旧的token值。

发表评论
作者:   用户:[访客] 
评论:

表  情
禁止表情 | 禁止UBB | 禁止图片 | 识别链接
对不起,你没有权限上传附件!
验证:
 
PoweredBy R-Blog V1.00 © 2004-2024 WWW.RICKW.CN, Processed in second(s) , 7 queries    京ICP备17058477号-5