【问题标题】:Easy way to password-protect php page密码保护php页面的简单方法
【发布时间】:2010-11-06 23:28:38
【问题描述】:

我想用密码保护一个页面。我尝试过进行 HTTP 身份验证,但由于某种原因,它在我的主机上不起作用。还有其他快速(简单)的方法吗?谢谢!

【问题讨论】:

  • 定义“不起作用”。
  • 这取决于很多事情。它只有一页吗?即使他们刷新页面,您是否需要访问者保持验证?你愿意使用会话吗?
  • 这只是一页,他们不需要保持验证。我宁愿不使用会话,除非有一种非常简单的方法可以不用表单等。

标签: php password-protection


【解决方案1】:

这里不是最强大的密码保护,所以请不要用它来保护信用卡号或非常重要的东西。

只需将以下所有代码放入名为 (secure.php) 的文件中,更改用户并从“admin”传递到您想要的任何内容。然后在包含(“secure.html”)的那些行下方,只需将其替换为您希望他们能够看到的文件名。

他们将在 [YouDomain.com/secure.php] 访问此页面,然后 PHP 脚本将在内部包含您想要密码保护的文件,因此他们将不知道该文件的名称,并且以后不能只是绕过密码提示直接访问它。

如果您想添加更高级别的保护,我建议您将 (secure.html) 文件放在站点根文件夹 [/public_html] 之外,并将其放在与该目录相同的级别,这样它不在目录中。然后在包含文件的 PHP 脚本中简单地使用 ("../secure.html")。那 (../) 表示返回目录以查找文件。这样做,人们可以访问 (secure.html) 页面上的内容的唯一方法是通过 (secure.php) 脚本。

<?php
$user = $_POST['user'];
$pass = $_POST['pass'];

if($user == "admin"
&& $pass == "admin")
{
        include("secure.html");
}
else
{
    if(isset($_POST))
    {?>

            <form method="POST" action="secure.php">
            User <input type="text" name="user"></input><br/>
            Pass <input type="password" name="pass"></input><br/>
            <input type="submit" name="submit" value="Go"></input>
            </form>
    <?}
}
?>

【讨论】:

  • 一种更安全的简单方法:不是存储密码,而是存储 md5 哈希。当他们尝试登录时,检查 md5($pass) 与哈希。更好的是,将 md5 哈希存储在公共 Web 根目录之外的文件中。
  • 您将受保护的页面存储在文档根目录之外是对的,因为在您的代码中,任何人都可以访问 secure.html 并绕过 PHP 脚本(除非您使用 .htaccess 文件或其他东西)。
  • 就像 willell 提到的,我再说一遍,无论如何不要把它当作一个安全的密码脚本。只是我在一两分钟内输入的内容,看起来可能符合要求,非常简单地需要通过才能看到页面。
  • @willell md5 现在被认为是不安全的。
  • 您可以通过将$a = 1 添加到您的登录页面,然后将if ($a != 1){ exit(); } 添加到您正在加载的安全页面来提高安全性。这应该可以防止未通过登录的访问页面。
【解决方案2】:

这有点晚了,但我想回复一下,以防其他人访问此页面并发现最高回复有点偏离。我对系统进行了一点改进。请注意,它仍然不是非常安全,但它是一种改进。

首先准备你的密码盐文件:

hash_generate.php:

 <?php

 $user = "Username"; // please replace with your user
 $pass = "Password"; // please replace with your passwd
 // two ; was missing

 $useroptions = ['cost' => 8,];
 $userhash    = password_hash($user, PASSWORD_BCRYPT, $useroptions);
 $pwoptions   = ['cost' => 8,];
 $passhash    = password_hash($pass, PASSWORD_BCRYPT, $pwoptions);

 echo $userhash;
 echo "<br />";
 echo $passhash;

 ?>

将您的输出 $userhash$passhash 分别放入两个文本文件:user.txt 和 pass.txt。其他人建议将这些文本文件放在 public_html 之上,这是个好主意,但我只是使用 .htaccess 并将它们存储在一个名为“stuff”的文件夹中

.htaccess

 deny from all

现在没有人可以窥探哈希。接下来是你的 index.php:

index.php:

<?php
$user = ""; //prevent the "no index" error from $_POST
$pass = "";
if (isset($_POST['user'])) { // check for them and set them so
    $user = $_POST['user'];
}
if (isset($_POST['pass'])) { // so that they don't return errors
    $pass = $_POST['pass'];
}    

$useroptions = ['cost' => 8,]; // all up to you
$pwoptions   = ['cost' => 8,]; // all up to you
$userhash    = password_hash($user, PASSWORD_BCRYPT, $useroptions); // hash entered user
$passhash    = password_hash($pass, PASSWORD_BCRYPT, $pwoptions);  // hash entered pw
$hasheduser  = file_get_contents("stuff/user.txt"); // this is our stored user
$hashedpass  = file_get_contents("stuff/pass.txt"); // and our stored password


if ((password_verify($user, $hasheduser)) && (password_verify($pass,$hashedpass))) {

    // the password verify is how we actually login here
    // the $userhash and $passhash are the hashed user-entered credentials
    // password verify now compares our stored user and pw with entered user and pw

    include "pass-protected.php";

} else { 
    // if it was invalid it'll just display the form, if there was never a $_POST
    // then it'll also display the form. that's why I set $user to "" instead of a $_POST
    // this is the right place for comments, not inside html
    ?>  
    <form method="POST" action="index.php">
    User <input type="text" name="user"></input><br/>
    Pass <input type="password" name="pass"></input><br/>
    <input type="submit" name="submit" value="Go"></input>
    </form>
    <?php 
} 

【讨论】:

  • 这是一个非常好的解决方案,尤其是当您保存密码的哈希值而不是纯文本时!现在考虑如果有人可以访问您的文件,他/她将不会寻找真正的密码,而是会使用受密码保护的页面。因此,此解决方案不会向受密码保护的页面添加任何内容,但它非常适合将密码保存在数据库中。
  • 为什么要评估 index.php 中的 $userhash 和 $passhash? (试图弄清楚为什么这段代码不起作用。 (password_verify($user, $hasheduser)) && (password_verify($pass,$hashedpass)) 总是为我返回 false。
  • 贝瑞,这是一篇很老的帖子。这更像是一种概念证明,而不是出于生产目的。我建议在存储您的业务逻辑而不是显示逻辑的地方验证数据
  • @BerryTsakala 条件句总是返回 false 可能是因为 file_get_contents("stuff/pass.txt") 也是行尾字符,而不仅仅是哈希。正如 Juan 在之前的评论中所说,将哈希存储在文件中并不是使用 password_verify 的最佳方式,但无论如何这段代码很好理解 password_hash 和 password_verify 的工作方式。
【解决方案3】:
<?php
$username = "the_username_here";
$password = "the_password_here";
$nonsense = "supercalifragilisticexpialidocious";

if (isset($_COOKIE['PrivatePageLogin'])) {
   if ($_COOKIE['PrivatePageLogin'] == md5($password.$nonsense)) {
?>

    <!-- LOGGED IN CONTENT HERE -->

<?php
      exit;
   } else {
      echo "Bad Cookie.";
      exit;
   }
}

if (isset($_GET['p']) && $_GET['p'] == "login") {
   if ($_POST['user'] != $username) {
      echo "Sorry, that username does not match.";
      exit;
   } else if ($_POST['keypass'] != $password) {
      echo "Sorry, that password does not match.";
      exit;
   } else if ($_POST['user'] == $username && $_POST['keypass'] == $password) {
      setcookie('PrivatePageLogin', md5($_POST['keypass'].$nonsense));
      header("Location: $_SERVER[PHP_SELF]");
   } else {
      echo "Sorry, you could not be logged in at this time.";
   }
}
?>

页面上的登录表单...
(在同一页面,就在上面^发布的代码的正下方)

<form action="<?php echo $_SERVER['PHP_SELF']; ?>?p=login" method="post">
<label><input type="text" name="user" id="user" /> Name</label><br />
<label><input type="password" name="keypass" id="keypass" /> Password</label><br />
<input type="submit" id="submit" value="Login" />
</form>

【讨论】:

【解决方案4】:

这是一个非常简单的方法。创建两个文件:

protect-this.php

<?php
    /* Your password */
    $password = 'MYPASS';

    if (empty($_COOKIE['password']) || $_COOKIE['password'] !== $password) {
        // Password not set or incorrect. Send to login.php.
        header('Location: login.php');
        exit;
    }
?>

login.php:

<?php
    /* Your password */
    $password = 'MYPASS';

    /* Redirects here after login */
    $redirect_after_login = 'index.php';

    /* Will not ask password again for */
    $remember_password = strtotime('+30 days'); // 30 days

    if (isset($_POST['password']) && $_POST['password'] == $password) {
        setcookie("password", $password, $remember_password);
        header('Location: ' . $redirect_after_login);
        exit;
    }
?>
<!DOCTYPE html>
<html>
<head>
    <title>Password protected</title>
</head>
<body>
    <div style="text-align:center;margin-top:50px;">
        You must enter the password to view this content.
        <form method="POST">
            <input type="text" name="password">
        </form>
    </div>
</body>
</html>

然后要求 protect-this.php 在要保护的文件的顶部:

// Password protect this content
require_once('protect-this.php');

示例结果:

填写正确密码后,用户被带到index.php。密码保存 30 天。

PS:重点不在于安全,而在于实用。黑客可以暴力破解这一点。用它来让普通用户远离。不要用它来保护敏感信息。

【讨论】:

  • 我在这里做了密码保护代码:github.com/henry7720/Verification-Page不需要30天cookies!
  • 文本框会记住输入的内容,因此当您将鼠标放回此处时,它会显示之前输入的单词。 ?!
  • 不要在此方法中使用用户生成的密码。用户倾向于重复使用密码并将其以纯文本形式存储为 cookie 可能会导致密码对其他来源可用。
  • @Henry7720,感谢这个项目,太棒了!它应该是公认的答案。
【解决方案5】:
Some easy ways:
Use Apache's digest authorization.
Use lighttpd's digest authorization.
Use php's header digest authorization.

如果你愿意,你也可以让它只有特定的 IP 地址才能登录.. :) 使用 lighttpd 真的很容易

更新:我将很快发布一些示例,所以不要为没有示例而投反对票,我只需要为这个答案写下一些。

如果您想使用会话,最好的方法是:

# admin.php
session_start();
if(!$_SESSION["AUTH"])
    require_once "login.php";
# Do stuff, we are logged in..

# login.php
session_start();
if($_REQUEST["username"] == "user" && $_REQUEST["password"] == "pass")
    $_SESSION["AUTH"] = true;
else $_SESSION["AUTH"] = false; # This logs you out if you visit this login script page without login details.

if($_SESSION["AUTH"])
    require_once "admin.php";

此方法不包含上述示例,但您对此方法很感兴趣。其他方法的例子还在后面,我没有足够的时间来获取 apache 或 lighttpd 设置和 php header auth: http://php.net/manual/en/features.http-auth.php 会做。

【讨论】:

    【解决方案6】:

    我会简单地寻找一个$_GET 变量,如果它不正确则重定向用户。

    <?php
    $pass = $_GET['pass'];
    if($pass != 'my-secret-password') {
      header('Location: http://www.staggeringbeauty.com/');
    }
    ?>
    

    现在,如果此页面位于:http://example.com/secrets/files.php

    您现在可以通过以下方式访问它:http://example.com/secrets/files.php?pass=my-secret-password 请记住,这不是最有效或最安全的方式,但它仍然是一种简单快捷的方式。 (另外,我知道我的答案已经过时,但其他人可能会觉得这个问题很有价值)

    【讨论】:

    • 不建议将任何类型的密码存储为 GET
    【解决方案7】:

    这帮了我很多,节省了我很多时间,它易于使用,运行良好,我什至冒着改变它的风险,它仍然有效。

    如果您不想浪费太多时间,那就太好了:)

    http://www.zubrag.com/scripts/password-protect.php

    【讨论】:

    • 我认为你的意思是:zubrag.com/scripts/password-protect.php 而不是
    • 已编辑! (好吧,已经有一段时间了,但我还是做到了:D)
    • 这在 2020 年仍然可以安全使用吗? @Baldráni
    • @vlovystack 我无法回答这个问题。但如果是我,我肯定会寻找更新版本。
    【解决方案8】:

    一种无需单独登录页面即可保护文件的简单方法 - 只需将其添加到页面顶部即可:

    将 secretuser 和 secretpassword 更改为您的用户/密码。

    $user = $_POST['user'];
    $pass = $_POST['pass'];
    
    if(!($user == "secretuser" && $pass == "secretpassword"))
    {
        echo '<html><body><form method="POST" action="'.$_SERVER['REQUEST_URI'].'">
                Username: <input type="text" name="user"></input><br/>
                Password: <input type="password" name="pass"></input><br/>
                <input type="submit" name="submit" value="Login"></input>
                </form></body></html>';
        exit();
    }
    

    【讨论】:

    • 这很好地防止了哑弹!
    【解决方案9】:
    </html>
    <head>
      <title>Nick Benvenuti</title>
      <link rel="icon" href="img/xicon.jpg" type="image/x-icon/">
      <link rel="stylesheet" href="CSS/main.css">
      <link rel="stylesheet" href="CSS/normalize.css">
      <script src="JS/jquery-1.12.0.min.js" type="text/javascript"></script>
    </head>
    <body>
    <div id="phplogger">
      <script type="text/javascript">
      function tester() {
      window.location.href="admin.php";
      }
      function phpshower() {
      document.getElementById("phplogger").classList.toggle('shower');
      document.getElementById("phplogger").classList.remove('hider');
      }
      function phphider() {
      document.getElementById("phplogger").classList.toggle('hider');
      document.getElementById("phplogger").classList.remove('shower');
      }
    </script>
    <?php 
    //if "login" variable is filled out, send email
      if (isset($_REQUEST['login']))  {
    
      //Login info
      $passbox = $_REQUEST['login'];
      $password = 'blahblahyoudontneedtoknowmypassword';
    
      //Login
      if($passbox == $password) {
    
      //Login response
      echo "<script text/javascript> phphider(); </script>";
      }
     }
    ?>
    <div align="center" margin-top="50px">
    <h1>Administrative Access Only</h1>
    <h2>Log In:</h2>
     <form method="post">
      Password: <input name="login" type="text" /><br />
      <input type="submit" value="Login" id="submit-button" />
      </form>
    </div>
    </div>
    <div align="center">
    <p>Welcome to the developers and admins page!</p>
    </div>
    </body>
    </html>
    

    基本上我在这里所做的就是在一个 php 文件中创建一个页面,当您输入密码时,如果密码正确,它将隐藏密码屏幕并将受保护的内容带到前面。然后是 css,这是一个关键部分,因为它使类可以隐藏和显示页面的不同部分。

      /*PHP CONTENT STARTS HERE*/
      .hider {
      visibility:hidden;
      display:none;
      }
    
      .shower {
      visibility:visible;
      }
    
      #phplogger {
      background-color:#333;
      color:blue;
      position:absolute;
      height:100%;
      width:100%;
      margin:0;
      top:0;
      bottom:0;
      }
      /*PHP CONTENT ENDS HERE*/
    

    【讨论】:

      【解决方案10】:

      你可以在你的 php 代码中指定一个密码,并且只允许拥有秘密 url 的用户:

      mywebsite.com/private.php?pass=secret
      

      在您的文件中:

      <?php
           if(isset($_GET["pass"] && $_GET["pass"]=="secret"){
                 //put your code here
           }
           else{
                 echo "you're not allowed to access this page";
           }
      ?>
      

      【讨论】:

        【解决方案11】:

        不是解决方案,而是为了您的利益:只有当 PHP 作为 Apache 模块运行时,HTTP 身份验证才有效。大多数主机只提供 PHP 作为 CGI 版本。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-09-12
          • 2018-09-15
          • 2016-03-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多