登录系统概念和逻辑?

Posted

技术标签:

【中文标题】登录系统概念和逻辑?【英文标题】:Login system concept & logic? 【发布时间】:2011-07-03 00:04:33 【问题描述】:

我想知道 Web 应用程序通常遵循哪些流程来维护多个请求之间的登录,以及它们如何使用 COOKIES 管理事物。

在我的登录表单中,我提供了“记住我”功能。

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

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

我没有检查会话值表单 db 以防止不必要地命中 db,加快速度。如果是cookie,可以修改,所以需要检查。

这是我的概念,对吗?这是要走的路吗?通常是像SO这样的网站,以及其他关于这种方法的作品?

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

请检查并给出你对这个场景的想法和概念。

谢谢!

【问题讨论】:

可能有用:User Membership With php @Prashant:请发邮件至shantanufrom4387@yahoo.com,需要私下讨论。也请阅读后删除。 【参考方案1】:

首先,只需跟踪是否有人登录。之后,我们将处理“记住我”功能。

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

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

if (isset($_SESSION['username'])) 
    // $_SESSION['username'] is logged in
 else 
    // nobody is logged in

$_SESSION中不需要存储密码(实际上,为了安全起见,最好不要将其存储在数据库中,除了散列之外的任何地方)。

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

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

对于第一点,假设您在 cookie 上存储了要“记住”的用户的用户名(非常不安全!!)。这意味着,如果任何用户为您的 Web 应用程序创建了一个包含“joe”内容的 cookie,您的应用程序会认为该用户 joe 已在该计算机中被记住,因此授予该攻击者访问权限,就好像他/她是 joe。所以,我们需要以某种方式加密/散列 cookie。

对于第二点,在某些计算机上使“记住我”无效,我们将以某种方式使用密码。如果某个用户想要使他/她可能选中“记住我”复选框的所有计算机无效,他/她所要做的就是更改他/她的密码。这也意味着如果他/她更改了他/她的密码,出于同样的原因,他/她的所有保存的登录信息都将失效。但安全总比后悔好...

因此,当您处理登录并且用户名和密码正确,并且选中“记住我”选项时,除了将用户名保存在会话中之外,您还存储用户名和密码的哈希(以及一些盐)在您​​发送给用户的 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...

在每个 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"

散列用户密码的方法取决于您。您可能喜欢纯 md5 或 sha、salted md5 或 sha(更好)或一些耗时的方法,如河豚(推荐)。 我使用普通 md5 来对 cookie 进行哈希处理,但您可以选择前面描述的任何方法。

我想就是这样。

【讨论】:

这是完全正确的。但是会话劫持或类似的可以破坏会话的东西呢?会话真的可以这么容易被攻破吗? 对于会话劫持攻击者需要访问会话 cookie。如果攻击者位于客户端和服务器之间的网络路由(中间人)或与客户端相同的非交换网络或相同的开放 wifi 网络中,则这是可能的。在这种情况下,攻击者可以嗅探流量,读取合法用户的会话 cookie 并劫持他的会话。对此的唯一防御是端到端加密 (SSL)。 攻击者获取合法用户会话cookie的其他方式是XSS攻击。要逃避这种攻击,您必须将输出转义到 html 页面(与在查询数据库之前转义值以避免 sql 注入的概念相同)。通过 XSS,攻击者可能会向您的应用程序注入一些 javascript,并且该 javascript 可能会尝试访问合法用户的会话 cookie。为避免任何 javascript 访问您的 cookie,请在 setcookie(...)session_set_cookie_params(...) 中使用 http_only 标志 感谢 Carlos,您的回答肯定会帮助我为我的应用程序正确设计登录系统 :) 永远不要在 cookie 中存储散列密码!一旦攻击者拥有哈希值,就非常容易获得真正的密码。现代登录系统仅保存为该用户生成的随机字符串的临时(!)散列。

以上是关于登录系统概念和逻辑?的主要内容,如果未能解决你的问题,请参考以下文章

vue+element ui+腾讯云开发打造会员管理系统之实战教程系统登录

业务逻辑:七完成系统菜单根据登录人动态展示

用户中心系统设计

10-单点登录系统拓展实现(自己尝试实现)

巧用jmeter逻辑控制器,解决压测中的登录问题

单点登录(SSO)-基础概念