簡體   English   中英

php 密碼保護網站

[英]php password protected website

我是網絡編程的新手,我試圖找到一些很好的示例/教程,以了解如何創建一個要求用戶登錄以查看主登錄頁面之外的任何頁面的網站的體面工作。

到目前為止,我已經找到了我嘗試過的 1 或 2 個,但我一直遇到同樣的問題。 如果我只是輸入我想手動查看的頁面的 url,我可以進入,就像那里什么都沒有。

好的,我將解釋基本概念是如何進行的,以及一個非常簡單的實現來讓事情順利進行。

PHP(和大多數 Web 應用程序)依賴於 RESTful 服務——就我們目前而言,這意味着每個請求都不會遠程綁定到任何其他請求——無論是來自同一用戶還是其他人。

那是什么意思呢?

這意味着對於每個請求,您都需要進行檢查。 您需要確保用戶是否有權執行該頁面,或者不太嚴重甚至可以查看其內容。

這是如何實現的?

從很多方面來說,實際上。 有許多技術可用於在 Web 應用程序上強制執行授權,但它們基本上都可以分解為兩種之一——集中式或分散式。

-- 集中式

這意味着您的所有操作(和控制器)都通過單個文件進行處理。 說 index.php。 然后,該文件將根據請求參數包含或委派其任務給其他文件(不能通過正常請求自行運行)。 這是一種非常流行的方法,但對於新開發人員來說並不完全是直接的。 使用此方法的應用程序示例將具有以下類型的 URL:index.php?do=register、index.php?do=login、index.php?do=showtopic&topic_id=2,等等。

這種技術的一個簡單實現如下:

<?php
// index.php
define('RUNNING_APP', true);
// 1. place your auth code here, or...
switch ($_REQUEST['do']) {
    case 'register':
        // 2. or here
        include 'inc/register.php';
        break;

    case 'do_register':
        // 2. and here, and before every include.. and so forth.
        include 'inc/do_register.php';
        break;
}
?>

<?php
// inc/register.php
defined('RUNNING_APP') or die('Cannot access this script directly'); // make sure to break direct access
?>
<form action="index.php?do=do_register">
<!-- form elements -->
</form>

等等。

我已經記錄了通常的身份驗證代碼應該放在哪里。

-- 去中心化

但是,使用這種方法,您的身份驗證代碼應該放在每個文件的開頭。 此類應用程序的 URL 通常類似於:register.php、login.php 等。 這里的主要問題是您需要對每個文件執行所有身份驗證邏輯,如上所述,如果您的文件數量增加,這可能是一項繁忙的工作。 一個方便的解決方案是將該邏輯放在單個文件中,並在您的任何邏輯之前包含該文件(這將終止對 unauth 人員的請求)。 一個簡單的例子是:

<?php
// index.php
include('inc/auth.php');
// index logic
?>

<?php
// register.php
include 'inc/auth.php';
// register logic
?>

<?php
// inc/auth.php
$logged_in = false;
if (!$logged_in) {
    die ('You do not have permission to access this page. Please login');
}
?>

使用表單登錄時,應檢查數據庫中的用戶名和密碼。 密碼應該被打亂(通常使用 MD5 哈希算法完成),並以相同的方式存儲在數據庫中。 您使用類似的方法捕獲變量(使用一些驗證來檢查 POST 變量是否有效):

$username = $_POST['username'];
$passwordHash = md5( $_POST['password'] );

用戶名和散列密碼應存儲在您的數據庫中。 然后,您可以使用以下方法檢查數據庫中的匹配項:

$res = mysql_query("SELECT * FROM users WHERE username='".$username."' && password='".$password."'");

找到用戶后,您可以使用會話來存儲用戶值,這將允許您跨頁面訪問用戶信息。 注意: session_start()通常放在頁面的頂部,但為了便於閱讀,我將它放在這里。

if ( mysql_num_rows($res) ) {
  session_start();
  session_regenerate_id(); // regenerate session_id to help prevent session hijacking
  $row = mysql_fetch_assoc($res);
  $_SESSION['logged_on'] = true;
  $_SESSION['username'] = $row['username'];
  // add more session variables about the user as needed
}

在您要保護的每個頁面上,將以下內容添加到這些頁面的頂部:

session_start();
if ( !isset($_SESSION['logged_on']) ) {
  header("Location: login.php"); // user is not logged in, redirect to login page
  exit;
}
// page content here

有 HTTP 身份驗證:

http://php.net/manual/en/features.http-auth.php

或者您可以使用登錄表單和會話跟蹤來推出自己的:

http://www.php.net/manual/en/book.session.php

Http auth 意味着用戶會收到一個彈出對話框窗口,要求輸入用戶名和密碼,這比自卷版本少見。

享受!

這與LordArtemis建議的內容相同,但本教程更容易理解並面向begginers。

http://css-tricks.com/easily-password-protect-a-website-or-subdirectory/

您提到的網站很可能可以繞過,因為通過安全檢查的頁面不會保存,然后檢查每個頁面上的登錄狀態。 在授予訪問頁面的權限之前,您需要檢查訪問者是否已登錄。

我認為大多數用戶都希望登錄時輸入表單。 如果您希望用戶在會話過期后返回並使用同一帳戶登錄,則需要一個數據庫來存儲用戶信息。

在數據庫中存儲用戶信息時,您可能也不應該實際存儲他們的密碼。 例如:

name    password                            ...
-----------------------------------------------
Johnny  '3858f62230ac3c915f300c664312c63f'
Alice   '80338e79d2ca9b9c090ebaaa2ef293c7'
.
.
.

Johnny 的密碼實際上是“foobar”,但數據庫存儲的是md5('foobar') 當 Johnny 嘗試登錄時,他輸入了他的用戶名 ('Johnny') 和他的密碼 ('foobar')。 在 PHP 中,您對他輸入的密碼進行哈希處理,並從數據庫中調用他的密碼值,結果為:

if (md5('foobar') == '3858f62230ac3c915f300c664312c63f')

這個條件是true 您可以確認他是否正確登錄,但您永遠不會存儲他的實際密碼。

Alice 的密碼是“foobaz”。 她試圖登錄,但不小心輸入了約翰尼的密碼“foobar”。 這導致:

if(md5('foobar') == '80338e79d2ca9b9c090ebaaa2ef293c7')

這是false 同樣,您不知道 Alice 的密碼什么,只知道她輸入了錯誤的密碼。

當然,這種策略的缺點是,當用戶忘記密碼時,您無法告訴他們密碼是什么——您不知道! 您可以通過讓用戶重置他們的密碼(到一些半隨機字符串)而不是嚴格告訴他們他們的密碼是什么來解決這個問題。

它不使用PHP進行身份驗證,但您可以使用htaccess提供身份驗證,並可能使用PHP管理.htpasswd文件:

http://www.freewebmasterhelp.com/tutorials/htaccess/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM