我感兴趣的是在登录页面上编写remember me
功能,该功能将在个人计算机上记录cookie一段时间。我知道这有危险,所以我想确保以正确的方式做到这一点。
我听说有人在数据库表和cookie本身之间建立链接以进行验证;但是,不知道如何做到这一点或是否建议。我是饼干的新手,所以请尽可能地解释一下。我没有任何例子,因为就像我说的那样,我以前从未对此进行过编码,并希望确保以正确的方式进行,并从已完成此操作的人那里获得输入。
我不确定facebook的饼干是否会永久存在,我只知道在我的电脑上我从未真正重新登录,除非我删除了我的历史记录。所以我可能想要这样做的方式类似。
提前致谢!
答案 0 :(得分:3)
我见过的最好的持久性Cookie技术之一是Barry Jaspan's:
- 当用户使用“记住我”选中成功登录时,除标准会话管理外,还会发出登录cookie cookie中。
- 登录cookie包含用户的用户名,系列标识符和令牌。系列和令牌是来自的不可取的随机数 适当的大空间。这三个都存储在一个数据库中 表
- 当未登录的用户访问该站点并显示登录cookie时,将在数据库中查找用户名,系列和令牌。
醇>
- 如果存在三元组,则认为用户已通过身份验证。使用的令牌将从数据库中删除。生成一个新令牌, 存储在数据库中的用户名和相同的系列标识符, 并向用户发出包含所有三个的新登录cookie。
- 如果存在用户名和系列但令牌不匹配,则假定盗窃。用户收到措辞强烈的警告 并删除所有用户记住的会话。
- 如果用户名和系列不存在,则忽略登录cookie。
我建议你阅读整篇文章,上面是要点。
此外,您只想通过SSL连接发出这些cookie,并在其上设置secure
和httponly
标志。
由于这意味着用户仅在通过SSL连接到服务器时进行了身份验证,我还设置了Strict-Transport-Security
HTTP标头以强制浏览器在将来始终使用SSL,另外还有一个简单的cookie,如{{1用于非SSL连接。如果浏览器通过非SSL连接访问该站点并且服务器看到persistent_login_available=yes
cookie,则会将访问者重定向到SSL版本并通过安全cookie对用户进行身份验证。
通过这个过程,您可以尽可能地保证安全。根据您的需要,可能可能会超出您的需求,您决定。
答案 1 :(得分:3)
我还没有为自己编写这个,但我会像这样解决问题:
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)
)
要填充此表,我会在登录中添加一些代码行,对于此示例,我将使用伪代码
// userID variable has been sanitized already so
// check if user clicked remember me
// and if the user logged in successfully:
if ( rememberMe == checked && login() == true )
{
// random number to serve as our key:
randomNumber = random( 99, 999999 );
// convert number to hexadecimal form:
token = toHex( ( randomNumber**randomNumber ) );
// encrypt our token using SHA1 and the randomNumber as salt
key = encrypt( token, randomNumber, SHA1 );
// get the number of seconds since unix epoch:
// (this will be 10 digits long until approx 2030)
timeNow = unix_time()
// check to see if user is in table already:
sql = "SELECT user_id FROM RememberMe
WHERE user_id = 'userID'";
// connect to database:
db = new DBCon();
result = db->query( sql );
// number of rows will always be 1 if user is in table:
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 );
// the affected rows will always be 1 on success
if ( result->affected_rows != 1 )
{
print( "A problem occurred.\nPlease log in again." );
quit();
}
result->free_memory();
// create a new cookie named cookiemonster and store the key in it:
// (we're not actually storing a score or birthday, its a false flag)
set_cookie( "CookieMonster", escape("score="+ userID +"birthday="+ key );
}
这段代码的作用是检查用户是否已经检查了记住我,并用一个密钥,一个令牌和一个用户的盐填充数据库表以及一个时间(这样你就可以强制执行时间限制了记得我的特色)。
从这里您可以添加代码到您的网站,检查 CookieMonster cookie是否已设置,是否您可以按照以下步骤强制执行其有效性:
从提供的cookie中提取用户ID和密钥
使用userID查询数据库以查看是否
--> a) user has requested to be remembered --> b) check the time to see if they cookie is still valid --> c) extract the token and salt from database table record
通过encrypt()函数调用运行token和salt并匹配 提出的密钥。
- 醇>
如果一切都结束,请创建一个新会话并将用户登录。
现在,每当用户访问您的网站时,他们都会登录,而如果他们的计算机遭到入侵,攻击者将无法访问他们的密码
备注:您应该始终要求您的用户在更改密码或电子邮件时提供密码,这样一来,如果用户的cookie找不到您的方式,攻击者将无法窃取该帐户。
答案 2 :(得分:2)
此策略被认为是最佳做法:请查看以下文章:http://jaspan.com/improved_persistent_login_cookie_best_practice