登录系统的概念和逻辑?

Pra*_*ant 5 php logic login-script concept

我想知道网络应用程序通常遵循的流程,以维护多个请求之间的登录,以及他们如何使用COOKIES管理事物.

在我的登录表单中,我提供"记住我"功能.

当用户登录时,我检查数据库的用户名和密码有效性.如果它有效,那么我检查是否选择了"记住我",如果是,则以会话,加密格式存储用户名和密码.最后在SESSION中存储用户名和密码.

当用户从一个页面导航到另一个页面时,首先我运行登录检查脚本,检查cookie中是否有任何值,然后验证数据库中的用户名和密码,以检查其有效性.如果cookie中没有值,并且会话中有一些值,那么我将从db中获取会话值并检查它.

我没有检查会话值表单db没有不必要地打db,加快了事情.如果是cookie,可以对其进行修改,因此需要进行检查.

这就是我的概念,是吗?它是通往网站的方式,以及其他类似方法吗?

或者网站检查每个页面加载的登录真实性,无论是在会话中还是在cookie中?

请检查并提供有关此方案的想法和概念.

谢谢!

Car*_*rós 14

首先,只是跟踪某人是否已登录.之后,我们将处理"记住我"功能.

要知道是否有人登录,您只需查看$_SESSION数组即可.那里的一切都是因为你之前把它放在那里.因此,在处理登录表单时,如果用户名和密码正确,则在会话中存储用户名,用户ID或其他内容($_SESSION['username'] = $username;).

每当用户加载任何页面时,您只需检查

if (isset($_SESSION['username'])) {
    // $_SESSION['username'] is logged in
} else {
    // nobody is logged in
}
Run Code Online (Sandbox Code Playgroud)

有没有需要存储密码的$_SESSION(事实上,为安全起见,最好不要存储在任何地方它除了在数据库散列).

现在,"记住我"的功能......首先,一些注意事项:

  • 任何用户都可以修改其浏览器的cookie,因此您需要确保发送到应用程序的cookie未被篡改.
  • 用户可以在公共计算机(库等)上检查,因此您需要一个系统来使其无效.
  • 如果用户退出您的应用程序,则必须删除记住他/她的cookie.

对于第一点,想象一下,在cookie上存储用户的用户名以"记住"(非常不确定!!).这意味着,如果任何用户使用内容"joe"为您的Web应用程序创建cookie,您的应用程序将认为用户joe在该计算机中被记住,因此授予此攻击者访问权,就好像他/她是joe一样.因此,我们需要以某种方式对cookie进行加密/散列.

对于第二点,在某些计算机上使"记住我"无效,我们将以某种方式使用密码.如果某些用户想要使他/她可能已经选中"记住我"复选框的所有计算机无效,则他/她所要做的就是更改他/她的密码.这也意味着,如果他/她更改了他/她的密码,他/她的帐户的所有已保存登录都将失效,原因完全相同.但更好的安全而不是抱歉......

因此,当您处理登录并且用户名和密码正确并且选中了"记住我"选项时,除了在会话中保存用户名外,您还存储了用户名和密码的哈希值(如果你的话,还有一些盐) will)在你发送给用户的cookie中.此外,您需要在cookie中以明文形式存储用户名(或以可反转的方式加密)以了解哪个用户试图通过cookie"登录",并检查cookie中的用户名和密码的哈希值.数据库中的用户名和密码.如果该检查正确,则将该用户名存储在会话中,不再检查该用户的cookie(至少对于此会话).

所以,整体而言你的代码可能如下所示:

的login.php

if (check_login($_POST['username'], $_POST['password'])) {
    // login correct
    $_SESSION['username'] = $_POST['username'];
    if (isset($_POST['remember_me'])) {
        // we hash the password because we **NEVER** store it in plain text anywhere
        // so when we would like to check if the cookie value is correct, we will not
        // be able to do so if the hash in the cookie was done from the plaintext
        // password.
        $value = sprintf('%s:%s', $_POST['username'], md5($_POST['username'].hash_password($_POST['password'])));
        setcookie('rememberme', $value);
    }
    redirect('/your/home/page.php'); // view Post/Redirect/Get design pattern
} else {
    // login incorrect, show error message and whatever...
}
Run Code Online (Sandbox Code Playgroud)

在每个php文件的开头(或更好,在包含的文件中引导您的应用程序)

if (isset($_SESSION['username'])) {
    // $_SESSION['username'] is logged in, proceed as you wish
} else if (isset($_COOKIE['rememberme'])) {
    // this user has checked the remember me feature some time ago in a previous login.
    // let's check if it is valid.
    list($username, $hash) = explode(':', $_COOKIE['rememberme']);

    // we need to get the password hash stored for this user (remember you **NEVER** store passwords in plain text
    $pwd_hash = obtain_password_hash_from_username($username);
    if ($hash == sprintf('%s:%s', $username, md5($username.$pwd_hash))) {
        // yeah, the user remembered is correct. We'll save it to the session to not do this shit again
        $_SESSION['username'] = $username;
    } else {
        // the cookie value is not correct so maybe an attacker is trying to fool us,
        // or the user changed his password. Whatever it is, we remove the cookie
        // because it's no longer valid
        setcookie('rememberme', '', time() - 3600);
    }

} else {
    // this user is neither logged in nor "remembered"
}
Run Code Online (Sandbox Code Playgroud)

哈希用户密码的方法取决于您.您可能喜欢简单的md5或sha,salted md5或sha(更好)或一些耗时的方法,如河豚(推荐).要散列cookie,我使用了普通的md5,但你可以选择任何早期描述的方法.

我认为就是这样.