如何创建一个安全的 php 登录系统,允许“保持登录状态”功能?

发布于 2024-08-15 06:50:32 字数 123 浏览 6 评论 0原文

我使用基于会话变量的简单登录系统。用户登录后,就会设置一个会话变量,告诉我的脚本要接受用户。我不使用任何自定义客户端 cookie 变量。

我想在登录屏幕上提供“让我全天登录”的选项。如何以一种安全的方式做到这一点?

I use a simple login system based on SESSION vars. Once the user logs in, a session var is set that tells my script the user is to be accepted in. I don't use any custom clientside cookie var.

I would like to offer the option on the login screen that says "keep me loggued in the whole day". How does one do that in a secure way?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

堇年纸鸢 2024-08-22 06:50:32

首先:配置 session.cookie_lifetime指令,可以在 php.ini、配置文件中,或者通过 session_set_cookie_params()

接下来,将用户名和密码的哈希值存储在会话中,并在每个页面上验证该登录。只要它仍然有效,他们就可以保持登录状态。

会话 cookie 的自然过期通常应该保持整洁,因为您不会让任何人在会话中途注销(如果星星对齐,或者当然)如果他们保持活跃的话。不过,如果做不到这一点,我会考虑 eCartoth 的解决方案紧随其后,因为您可以在 if 语句中添加第二行:

if (my_validate_user_function($_SESSION['username'],$_SESSION['passhash']) 
    && $_SESSION['deathstamp'] > time()
) {
    // user is logged in again, oh boy!
}
else {
    // send in the death robots
    header('Location: /login.php',true,302);
}

编辑:您可能需要考虑的一件事是会话固定和/或会话劫持。为了防止这种情况,我建议使用以下两种解决方案中的一种(或两种):

  1. 将用户的 IP 地址存储在会话中,
  2. 使用 session_regenerate_id() 在每次成功登录尝试后。

First: Configure the session.cookie_lifetime directive, either in php.ini, configuration files, or via session_set_cookie_params().

Next, store the username and the hash value of the password in the session, and validate that login on every page. As long as it's still valid, they get to stay logged in.

The session cookie's natural expiration should generally keep things tidy, as you won't have anyone getting logged out in the middle of their session (if the stars aligned for it, of course) if they keep it active. Failing that, though, I'd consider eCartoth's solution a close second, as you could just add a second line to the if statement:

if (my_validate_user_function($_SESSION['username'],$_SESSION['passhash']) 
    && $_SESSION['deathstamp'] > time()
) {
    // user is logged in again, oh boy!
}
else {
    // send in the death robots
    header('Location: /login.php',true,302);
}

EDIT: One thing you might want to consider is session fixation and/or session hijacking. In order to prevent that, I'd recommend one (or both) of two solutions:

  1. store the user's IP address in the session
  2. use session_regenerate_id() after every successful login attempt.
川水往事 2024-08-22 06:50:32

当您说“让我全天登录”时,我假设您的意思是仅在那台特定计算机上,对吗?您可以使用 mysql 表来记住“登录时间”,或者如果他们选择全天登录,则该登录将不再有效的时间戳。然后在代码开头添加一些脚本,从会话变量中检索该用户的 id。将该用户的当前时间戳与存储的“最后有效 ts”进行比较,如果超过了该时间,您就知道他们应该被注销,此时您将擦除会话并强制用户再次登录。这种方法意味着他们实际上不会被注销,直到他们尝试做一些超过该点的事情,但对他们来说似乎就是这样。此外,您还可以将最后一个有效的 TS 存储在会话变量中,而不是使用 mysql DB。

例如,当用户首次登录时选择“选择全天保持登录”:

$_SESSION['log_me_out_at'] = strtotime(date("Y-m-d ")."23:59:59");

然后每次在系统中访问页面时:

if( $_SESSION['log_me_out_at'] < time() ){
  unset($_SESSION['user_is_accepted_in']);
}

When you say "keep me logged in the whole day", I'm assuming you mean on that specific machine only, correct? You could use a mysql table to remember 'time of login', or a timestamp of when that login will no longer be valid if they choose to keep themselves logged in all day. Then add some script to the beginning of your code that retrieves the id of that user from the session vars. Compare the current timestamp of that user against the stored 'last valid ts' and if it's past that time, you know they should be logged out, at which point you wipe the session and force the user to log in again. This method means they won't actually be logged out until they try and do something past that point, but it will seem like it to them. Also, rather than using a mysql DB you could also store that last valid TS in a session variable as well.

So for example when the user first logs in with "keep me logged in all day selected":

$_SESSION['log_me_out_at'] = strtotime(date("Y-m-d ")."23:59:59");

Then each time a page is accessed in your system:

if( $_SESSION['log_me_out_at'] < time() ){
  unset($_SESSION['user_is_accepted_in']);
}
固执像三岁 2024-08-22 06:50:32

一种选择可能是设置一个 MySQL 表来保存会话变量并将它们与 IP 地址和过期时间相关联,但我不确定如何实现的所有细节。

执行您要查找的操作的最简单(尽管不推荐)方法是使用计算机上的用户名和密码设置 $_COOKIE,您的网站将使用该用户名和密码然后检查用户何时登录。

为了提高安全性,您最好只保存一个 cookie 作为用户数据的加盐 MD5 哈希值,以便为潜在的黑客提供较少的有关用户帐户数据的信息。设置cookie时可以设置持续时间; php.net 有相当完整的文档说明如何做到这一点。

One option could be to set up a MySQL table that saves session variables and associates them with IP addresses and an expiration, but I'm not sure of all the details on how that would be implemented.

The simplest (though not recommended) way to do what you're looking for would be to set a $_COOKIE with the username and password on the computer, which your site will then check for when the user signs on.

For added security, you would be better served to save just one cookie as a salted MD5 hash of the user's data in order to provide a potential hacker less information about the user's account data. The duration can be set when you set the cookie; php.net has reasonably complete documentation on how to do that.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文