设置“记住我”功能的最安全方法是设置一个cookie。
设置“记住我”功能的最安全方法是设置一个cookie。
我对在登录页面上编写一个“记住我”功能很感兴趣,它会在用户的计算机上记录一个 cookie,保存一段时间。我知道这样做存在一些危险,所以我希望确保采用正确的方法。
我听说有人在数据库表和 cookie 之间创建了一个链接,用于验证;但是,我不知道如何做这个,也不确定是否被推荐。我对 cookie 还不太熟悉,请尽可能详细地解释最佳的方法。我没有任何示例,因为如我所说,我以前从未编写过这个功能,我希望确保采用正确的方法,并从已经实现过的人那里获得意见。
我不确定 Facebook 的 cookie 是否永久保存,我只知道在我的计算机上,除非我删除浏览历史记录,否则我几乎不需要重新登录。所以我可能希望采用类似他们的方式来实现。
提前感谢!
在这段内容中,作者介绍了一种设置“记住我”功能的最安全的cookie方法。作者建议使用以下步骤来实现:
1. 当用户成功通过勾选“记住我”选项登录时,除了标准的会话管理cookie之外,还会发出一个登录cookie。
2. 登录cookie包含用户的用户名、一个系列标识符和一个令牌。系列标识符和令牌都是从一个足够大的随机数空间中生成的不可预测的值。这三个值一起存储在数据库表中。
3. 当一个非登录用户访问网站并提供登录cookie时,会在数据库中查找用户名、系列标识符和令牌。
- 如果这个三元组存在,用户被视为已经认证。使用过的令牌从数据库中删除。生成一个新的令牌,与用户名和相同的系列标识符一起存储在数据库中,并发放一个包含这三个值的新的登录cookie给用户。
- 如果用户名和系列标识符存在,但令牌不匹配,则认为发生了盗窃。用户会收到一个强烈的警告,并删除用户的所有记住的会话。
- 如果用户名和系列标识符不存在,则忽略登录cookie。
作者还建议仅在SSL连接上发放这些cookie,并在其上设置secure和httponly标志。由于这意味着用户只能在通过SSL连接与服务器连接时进行认证,作者还额外设置了Strict-Transport-Security HTTP头,以强制浏览器将来始终使用SSL。此外,对于非SSL连接,还设置了一个简单的cookie(persistent_login_available=yes)。如果浏览器通过非SSL连接访问网站并且服务器看到了persistent_login_available cookie,则将访问者重定向到SSL版本,并通过安全cookie对用户进行认证。
,通过以上步骤设置的cookie可以达到最高的安全性水平。不过,对于一般需求来说,这个方法可能有些过于复杂,你可以根据自己的需要决定是否采用。
最后,作者感谢这篇文章,并表示对于如何编写这个功能也不太确定,但在下方的评论中有人给出了一个编写代码的示例。作者希望能够得到读者对这段代码的整体概念的意见,并确认它是否是一个好的代码。
文章标题:设置“记住我”功能的最安全方式
在开发“记住我”功能时,我们希望确保用户的登录信息能够持久保存,并且能够在用户再次访问网站时自动登录。为了实现这个功能,我们需要解决以下两个问题:如何将用户的登录信息保存在数据库中,并且如何验证保存的登录信息的有效性。
为了解决这个问题,我会按照以下步骤进行操作:
1. 首先,创建一个数据库表,用于在用户提交cookie时进行有效性检查:
create table RememberMe ( user_id int(10) NOT NULL, user_token char(10) NOT NULL, token_salt int(6) NOT NULL, time int(10) NOT NULL, PRIMARY KEY (user_id), CONSTRAINT nameYourConstraint FOREIGN KEY (user_id) REFERENCES userTableName (whatever_user_id_equals) )
2. 在登录过程中,添加以下代码来向数据库表中添加数据(伪代码):
// 检查用户是否勾选了“记住我”选项,并且用户成功登录 if ( rememberMe == checked && login() == true ) { // 生成随机数作为密钥 randomNumber = random( 99, 999999 ); // 将随机数转换为十六进制形式 token = toHex( ( randomNumber**randomNumber ) ); // 使用SHA1和随机数作为盐对密钥进行加密 key = encrypt( token, randomNumber, SHA1 ); // 获取当前时间戳 timeNow = unix_time() // 检查用户是否已经存在于表中 sql = "SELECT user_id FROM RememberMe WHERE user_id = 'userID'"; // 连接数据库 db = new DBCon(); result = db->query( sql ); // 如果查询结果的行数不等于1,则用户已存在于表中 if ( result->rows != 1 ) exists = true; else exists = false; result->free_memory(); if ( exists == true ) { sql = "UPDATE RememberMe SET user_id = 'userID' user_token = 'token' token_salt = 'randomNumber' time = 'timeNow'"; } else { sql = "INSERT INTO RememberMe VALUES( 'userID', 'token', 'randomNumber', 'timeNow' )"; } result = db->query( sql ); // 如果影响的行数不等于1,则出现问题 if ( result->affected_rows != 1 ) { print( "出现问题,请重新登录。" ); quit(); } result->free_memory(); // 创建一个名为cookiemonster的新cookie,并将密钥存储在其中 set_cookie( "CookieMonster", escape("score="+ userID +"birthday="+ key ); }
通过以上代码,我们可以检查名为“CookieMonster”的cookie是否存在,并且按照以下步骤验证其有效性:
1. 从cookie中提取用户ID和密钥
2. 使用用户ID查询数据库,判断:
- 用户是否请求保持登录状态
- cookie是否仍然有效
- 从数据库表中提取token和salt
3. 将token和salt传递给encrypt()函数进行加密,并与提供的密钥进行比较
4. 如果验证通过,创建一个新的会话并登录用户
现在,每当用户访问网站时,他们将自动登录,并且在计算机被攻击时,攻击者无法获得他们的密码。
附注:无论何时用户更改密码或电子邮件,您都应要求用户提供密码。这样,即使用户的cookie落入错误的手中,攻击者也无法窃取账户。
文章结束。