如何检查用户是不是在 php 中登录?

Posted

技术标签:

【中文标题】如何检查用户是不是在 php 中登录?【英文标题】:How can I check if a user is logged-in in php?如何检查用户是否在 php 中登录? 【发布时间】:2010-12-05 10:42:09 【问题描述】:

我对 php 还很陌生,我正在尝试弄清楚如何使用会话来检查用户是否登录到网站,以便他们有权访问特定页面。

这是复杂的事情还是因为我是一个菜鸟我无法弄清楚?

【问题讨论】:

是的,但我正在寻找能以我能理解的方式解释它的人,非常感谢! 【参考方案1】:

登录并不太复杂,但有一些几乎所有登录过程都需要的特定部分。

首先,确保在所有需要了解登录状态的页面上启用会话变量,方法是将其放在这些页面的开头:

session_start();

接下来,当用户通过登录表单提交用户名和密码时,您通常会通过查询包含用户名和密码信息的数据库(例如 mysql)来检查他们的用户名和密码。如果数据库返回匹配项,则您可以设置会话变量以包含该事实。您可能还想包含其他信息:

if (match_found_in_database()) 
    $_SESSION['loggedin'] = true;
    $_SESSION['username'] = $username; // $username coming from the form, such as $_POST['username']
                                       // something like this is optional, of course

然后,在取决于登录状态的页面上,输入以下内容(不要忘记session_start()):

if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] == true) 
    echo "Welcome to the member's area, " . $_SESSION['username'] . "!";
 else 
    echo "Please log in first to see this page.";

这些是基本组件。如果您需要有关 SQL 方面的帮助,网上有很多教程。

【讨论】:

感谢您的解释。我想知道是否可以限制文件夹而不是页面?所以除非您登录,否则我在该文件夹中的任何页面都受到限制?【参考方案2】:

此页面上的几乎所有答案都依赖于检查会话变量的存在来验证用户登录。这绝对没问题,但重要的是要考虑到,如果同一裸机上有多个虚拟主机/站点,PHP 会话状态并不是您的应用程序所独有的。

如果您在网络服务器上有两个 PHP 应用程序,都使用名为“isLoggedIn”的会话变量中的布尔标志检查用户的登录状态,那么用户可以登录其中一个应用程序,然后自动获得对第二个应用程序的访问权限没有凭据。

我怀疑即使是最恐龙的商业共享主机也不会让虚拟主机共享相同的 PHP 环境,这种情况可能会发生在多个客户站点的(不再),但在您自己的环境中需要考虑这一点。

非常简单的解决方案是使用标识应用程序的会话变量而不是布尔标志。例如 $SESSION["isLoggedInToExample.com"]

来源:我是一名渗透测试员,对你不应该做的事情有很多经验。

【讨论】:

这是一个有效的点。在大多数用例中,您将会话登录布尔标志与附加的会话变量(例如用户令牌)一起存储,该变量可用于在提供访问权限之前完全验证用户。但如前所述,$SESSION["isLoggedInToExample.com"] 是比 $SESSION["loggedIn"] 更好的方法,但我希望在授予访问权限之前也验证一个唯一字段。 我认为以上内容可能足以验证对站点的访问,因为它来自 cookie……暗示某种基于表单的身份验证已经发生。除此之外,您仍然可以对更细粒度的用户访问控制执行额外检查;取决于您运行的网站类型。 会话信息的安全性如何?我知道它存储在服务器上的tmp 目录中。攻击者可以修改会话数据以登录吗?这是我应该关心的事情吗?另外,我应该避免在会话中存储加密密钥吗? 我认为您在@IndianaKernick 那里提出了一个新问题。会话数据是安全的,因为它不在 Web 根目录中。但它可能永远不是加密密钥的合适位置。您需要一个对任何敏感内容具有适当访问控制的数据库。即使使用会话存储来缓存用户数据,如果它的 PII 也是有风险的。您通常最好还是返回数据库或寻找替代解决方案。【参考方案3】:

警告:以下答案包含一个易受 SQL 注入攻击的高度易受攻击的示例。它永远不应部署在生产环境中,并且通常被认为已被高度弃用。

您应该只将此答案视为示例或对事物如何工作的一般概念。

更好的实现包括:

PDO in PHP MySQLi 对用户输入进行了适当的清理。

原始答案从这里开始:

在文件Login.html

<html>
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  <title>Login Form</title>
</head>
<body>
  <section class="container">
    <div class="login">
      <h1>Login</h1>
      <form method="post" action="login.php">
        <p><input type="text" name="username" value="" placeholder="Username"></p>
        <p><input type="password" name="password" value="" placeholder="Password"></p>

        <p class="submit"><input type="submit" name="commit" value="Login"></p>
      </form>
    </div>
</body>
</html>

在文件Login.php

<?php
    $host="localhost"; // Host name
    $username=""; // MySQL username
    $password=""; // MySQL password
    $db_name=""; // Database name
    $tbl_name="members"; // Table name

    // Connect to the server and select a database.
    mysql_connect("$host", "$username", "$password") or die("cannot connect");
    mysql_select_db("$db_name") or die("cannot select DB");

    // Username and password sent from the form
    $username = $_POST['username'];
    $password = $_POST['password'];

    // To protect MySQL injection (more detail about MySQL injection)
    $username = stripslashes($username);
    $password = stripslashes($password);
    $username = mysql_real_escape_string($username);
    $password = mysql_real_escape_string($password);
    $sql = "SELECT * FROM $tbl_name WHERE username='$username' and password='$password'";
    $result = mysql_query($sql);

    // Mysql_num_row is counting the table rows
    $count=mysql_num_rows($result);

    // If the result matched $username and $password, the table row must be one row
    if($count == 1)
        session_start();
        $_SESSION['loggedin'] = true;
        $_SESSION['username'] = $username;
    

在文件Member.php中:

session_start();
if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] == true) 
    echo "Welcome to the member's area, " . $_SESSION['username'] . "!";

else 
    echo "Please log in first to see this page.";

在 MySQL 中:

CREATE TABLE `members` (
    `id` int(4) NOT NULL auto_increment,
    `username` varchar(65) NOT NULL default '',
    `password` varchar(65) NOT NULL default '',
    PRIMARY KEY (`id`)
) TYPE=MyISAM AUTO_INCREMENT=2 ;

在文件Register.html中:

<html>
    <head>
        <title>Sign-Up</title>
    </head>

    <body id="body-color">
        <div id="Sign-Up">
            <fieldset style="width:30%"><legend>Registration Form</legend>
                <table border="0">
                    <form method="POST" action="register.php">
                        <tr>
                            <td>UserName</td><td> <input type="text" name="username"></td>
                        </tr>

                        <tr>
                            <td>Password</td><td> <input type="password" name="password"></td>
                        </tr>

                        <tr>
                            <td><input id="button" type="submit" name="submit" value="Sign-Up"></td>
                        </tr>
                    </form>
                </table>
            </fieldset>
        </div>
    </body>
</html>

在文件Register.php中:

<?php
    define('DB_HOST', '');
    define('DB_NAME', '');
    define('DB_USER','');
    define('DB_PASSWORD', '');

    $con = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD) or die("Failed to connect to MySQL: " . mysql_error());
    $db = mysql_select_db(DB_NAME, $con) or die("Failed to connect to MySQL: " . mysql_error());

    $userName = $_POST['username'];
    $password = $_POST['password'];
    $query = "INSERT INTO members (username,password) VALUES ('$userName', '$password')";
    $data = mysql_query ($query) or die(mysql_error());
    if($data)
    
        echo "Your registration is completed...";
    
    else
    
        echo "Unknown Error!"
    

【讨论】:

mysql_* 在 2014 年? mysql_real_escape_string is depricated。 Use PDO instead. 不要使用这个脚本。它已经过时并且可能受到注入攻击。 因将高度易受攻击的脚本作为操作指南而被否决。 这种方法很古老,极易发生 SQL 注入。要么使用 MySQLi 而不是 MySQL(并仔细清理任何用户输入),要么使用 PDO 更好。【参考方案4】:

您想要对其执行会话检查的任何页面都需要从以下开始:

session_start();

从那里,您可以检查会话数组中是否存在表明他们已登录的变量:

if (!$_SESSION["loggedIn"]) redirect_to_login();

登录它们只不过是设置该值:

$_SESSION["loggedIn"] = true;

【讨论】:

【参考方案5】:

在检查当前会话之前,您需要在所有页面上使用它:

session_start();

检查$_SESSION["loggedIn"](不是)是否为真 - 如果不是,则将其重定向到登录页面。

if($_SESSION["loggedIn"] != true)
    echo 'not logged in';
    header("Location: login.php");
    exit;

【讨论】:

【参考方案6】:

请参阅此脚本以进行注册。它简单易懂。

<?php
    define('DB_HOST', 'Your Host[Could be localhost or also a website]');
    define('DB_NAME', 'database name');
    define('DB_USERNAME', 'Username[In many cases root, but some sites offer a MySQL page where the username might be different]');
    define('DB_PASSWORD', 'whatever you keep[if username is root then 99% of the password is blank]');

    $link = mysql_connect(DB_HOST, DB_USERNAME, DB_PASSWORD);

    if (!$link) 
        die('Could not connect line 9');
    

    $DB_SELECT = mysql_select_db(DB_NAME, $link);

    if (!$DB_SELECT) 
        die('Could not connect line 15');
    

    $valueone = $_POST['name'];
    $valuetwo = $_POST['last_name'];
    $valuethree = $_POST['email'];
    $valuefour = $_POST['password'];
    $valuefive = $_POST['age'];

    $sqlone = "INSERT INTO user (name, last_name, email, password, age) VALUES ('$valueone','$valuetwo','$valuethree','$valuefour','$valuefive')";

    if (!mysql_query($sqlone)) 
        die('Could not connect name line 33');
    

    mysql_close();
?>

确保确保您使用phpMyAdmin 制作所有数据库内容。这是一个非常容易使用的工具。你可以在这里找到它:phpMyAdmin

【讨论】:

这不仅没有回答原始问题,而且也是一个糟糕的例子。该脚本对 SQL 注入开放,从个人角度来看,我不会向任何人推荐 phpmyadmin。【参考方案7】:

你可以做一个会话并放置它:

// Start session
session_start();

// Check do the person logged in
if($_SESSION['username']==NULL)
    // Haven't log in
    echo "You haven't log in";
else
    // Logged in
    echo "Successfully logged in!";

注意:您必须制作一个包含$_SESSION['username'] = $login_input_username;的表单

【讨论】:

【参考方案8】:
else if (isset($_GET['actie']) && $_GET['actie']== "aanmelden")

    $username= $_POST['username'];
    $password= md5($_POST['password']);
    $query = "SELECT password FROM tbl WHERE username = '$username'";
    $result= mysql_query($query);
    $row= mysql_fetch_array($result);

    if($password == $row['password'])
            session_start();
            $_SESSION['logged in'] = true;
            echo "Logged in";

    

【讨论】:

此代码易受 SQL 注入攻击,您不应该在 2019 年将密码存储为 MD5 哈希,它使用了已弃用的 PHP 函数,并且带有零解释。这是一个糟糕的答案,应该删除。 另外,由于没有错误检查...可能会强制 $row 和 $password 值为 FALSE,从而绕过登录。我刚刚检查过,md5() 在失败时返回 FALSE 值......所以将密码值作为数组而不是字符串发送会绕过它。 即使作为蓝图,这也让我热血沸腾。只有在密码正确的情况下才会调用 session_start()。那么那些已登录但不知何故最终尝试使用错误凭据再次登录的人呢?......他们是否会在下一个响应时被踢,但是如果他们导航到另一个页面,他们又会神奇地再次登录? session_start() 应该存在于其他地方。 我可以写一本关于为什么我讨厌这个答案的书。

以上是关于如何检查用户是不是在 php 中登录?的主要内容,如果未能解决你的问题,请参考以下文章

PHP:如何检查用户是不是已经登录,否则重定向到登录页面

WordPress - 检查用户是不是登录

如何在目标c中检查用户是不是登录?

Symfony 2:如何检查用户是不是未在模板中登录?

如何检查用户是不是登录

如何在jsp中应用检查当前用户是不是登录