2010-02-12 79 views
6

我有一個LAMP設置,我只想保護網頁上的內容(圖像,CSS,視頻等),以便只有登錄的用戶才能訪問它。限制使用PHP登錄用戶的內容訪問

我知道我可以用.htaccess輕鬆做到這一點。不過,我不想使用身份驗證彈出窗口,我希望能夠使用會話並能夠註銷。

我正在使用php來完成使用mysql進行身份驗證和創建會話的工作。這很好。但圖像,CSS,JavaScript等仍然可以訪問。

我怎麼只允許訪問,如果一個有效的PHP會話存在的內容?

我遇到過使用mod_rewrite將文件轉發到php文件(如auth.php?file = ...)並在那裏進行會話檢查。這對於檢查已經檢查的頁面中的每個單個圖像的會話似乎是低效的。這似乎是一個黑客,我一直認爲有一個更乾淨的方式來做到這一點。

是否有阿帕奇像mod_session_cookie,可以檢查是否有一個會話密鑰的Cookie,以我的會話數據庫中,如果存在,那麼從集合所有目錄允許國防部?

或者,是否有可能使用mod_auth_mysql,但也可以使用使用PHP的形式,而不是認證彈出會話和登錄?

編輯:

這裏是我的問題的解決方案:

在我的Apache配置文件(沒有的.htaccess)我說:

RewriteLock /var/www/lib/rewrite.lock 

<VirtualHost> 
    #... 
    RewriteEngine on 
    RewriteMap sessionValid prg:/var/www/lib/allow.php 

    <Directory /var/www/client/*> 
      RewriteEngine on 

      RewriteCond %{HTTP_COOKIE} !client-cookie=([^;]+) 
      RewriteRule .* - [L,R=403] 

      RewriteCond %{HTTP_COOKIE} client-cookie=([^;]+) 
      RewriteCond ${sessionValid:%1} !valid 
      RewriteRule .* - [L,R=403] 
    </Directory> 
</VirtualHost> 

和腳本允許.PHP:

#!/usr/bin/php5 
<?php 
set_time_limit(0); 

echo ""; 
$stdin = fopen("php://stdin","r"); 
$db = mysql_connect(...); 
mysql_select_db(..., $db); 
$querypre = "SELECT ID FROM Sessions WHERE ID='"; 

while (1) { 
    $line = trim(fgets($stdin)); 

    $query = $querypre.mysql_real_escape_string($line)."'"; 
    $result = mysql_query($query); 

    if (mysql_num_rows($result) > 0) 
    echo("valid\n"); 
    else 
    echo("0\n"); 
} 

mysql_close($db); 
?> 

這工作就像一個魅力。使用這個和session_set_save_handler我能夠使用MySQL支持的php會話來保護php頁面和所有內容。我希望有人認爲這很有用。

一些注意事項:

  • 的RewriteMap指令語句需要虛擬主機塊裏面定義的,如果你要使用它的是虛擬主機內。將它放在塊之外將不起作用。
  • 在定義RewriteMap之前,您必須先設置RewriteEngine,否則它將被忽略。
  • RewriteLock不能在虛擬主機塊中。
  • 與任何shell腳本,php文件必須是由Apache用戶和^無效M的
  • RewriteMap指令語句不能放置在.htaccess但使用地圖可以在其他語句執行。

回答

5
RewriteCond %{HTTP_COOKIE} !mysessioncookie=([^;]+) 
RewriteRule .+\.(jpg|css|js) forbidden.html [R=403] 
+1

原諒我沒有在我的Apache-fu上 - 是否比檢查cookie的存在做得更多? – 2010-02-12 01:05:42

+0

@Bock:N ope。 – 2010-02-12 01:08:54

+1

那麼這難道不是很容易規避嗎? OP希望cookie能夠在他的數據庫中進行適當的會話驗證。 – 2010-02-12 01:11:14

0

而是直接鏈接到資源,使用某種形式的控制器來服務圖像。

例如,鏈接到'images/bob。jpg'實際上並不指向資源,而是一個腳本,用於檢查登錄,如果成功,則發送帶有正確數據的image/jpeg標頭。

+0

他在他的回答中注意到了這種技巧;他問是否有一個替代方案不需要腳本來運行每一個內容。 – 2010-02-12 01:00:37

0

我其實不用Apache;我使用lighttpd,它包含一個插件,您可以使用該插件根據URI中是否傳遞正確的哈希來限制對文件夾的訪問。基本上,您的應用程序邏輯和Web服務器共享一個祕密salt,然後用它來生成當前時間的散列值,這個散列值也與散列值一起傳遞。如果時間在過去5分鐘內,則授予訪問權限。如果不是,或者散列無效,那麼它不會。我正在搜索,看看目前是否有類似的Apache插件。

編輯:mod_auth_token似乎對Apache做同樣的事情。

+0

不幸的是,這似乎需要更改網址,這對我來說不是一種選擇。 – Luke 2010-02-12 02:07:25