2010-02-12 6 views
6

Mam konfigurację LAMPY i chcę tylko chronić zawartość strony (obrazy, css, wideo itp.), Aby tylko zalogowani użytkownicy mieli do niej dostęp.Ograniczanie dostępu do treści zalogowanym użytkownikom za pomocą PHP

Zdaję sobie sprawę, że mogę to łatwo zrobić dzięki .htaccess. Nie chcę jednak korzystać z wyskakującego okna uwierzytelniania i chcę móc korzystać z sesji, a także móc się wylogować.

Używam php do zadania uwierzytelniania z mysql i tworzenia sesji. Działa to świetnie. Ale obrazy, css, javascript itp. Są nadal dostępne.

Jak mogę zezwolić na dostęp do treści tylko wtedy, gdy istnieje ważna sesja php?

Natknąłem się za pomocą mod_rewrite do przesyłania plików do pliku php (jak auth.php? File = ...) i do sprawdzania sesji tam. Wydaje się to nieskuteczne, aby sprawdzić sesję dla każdego obrazu na stronie, która została już sprawdzona. Wygląda to jak włamanie i ciągle myślę, że istnieje czystszy sposób robienia tego.

Czy istnieje mod dla apache takich jak mod_session_cookie, które mogą sprawdzić, czy plik cookie z klucz sesja istnieje w mojej sesji bazy danych, a jeśli tak to ustawić Zezwalaj wszystkim na katalog?

Alternatywnie, czy możliwe jest użycie mod_auth_mysql, ale także możliwość korzystania z sesji i logowania za pomocą formularza php, a nie wyskakującego okna uwierzytelniania?

EDIT:

Oto moje rozwiązanie problemu:

W moim pliku konfiguracyjnego Apache (nie .htaccess) I dodaje:

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> 

i skrypt umożliwienia .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); 
?> 

Działa to jak urok. Używając tego i session_set_save_handler udało mi się skorzystać z sesji php wspieranych przez mysql, aby zabezpieczyć zarówno strony php, jak i całą zawartość. Mam nadzieję, że ktoś uzna to za przydatne.

Niektóre Ostrzeżenia:

oświadczenie
  • RewriteMap musi być zdefiniowana wewnątrz bloku wirtualnego hosta, jeśli masz zamiar używać go wewnątrz tego wirtualnego hosta. Umieszczenie go poza blokiem nie będzie działać.
  • Musisz mieć ustawiony RewriteEngine przed zdefiniowaniem RewriteMap lub zostanie on zignorowany.
  • RewriteLock nie może znajdować się w bloku hosta wirtualnego.
  • Jak w każdym skrypcie, plik php musi być wykonywalny przez użytkownika apache i pustkę^
  • oświadczenia RewriteMap M nie mogą być umieszczone w pliku .htaccess, ale z drugiej wypowiedzi, które korzystają z MAP.

Odpowiedz

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

Wybacz mi, że nie jestem na moim Apache-fu - czy to coś więcej niż sprawdzanie istnienia ciasteczka? –

+0

@Brock: N ope. –

+1

Czy nie byłoby to niewiarygodnie łatwe do obejścia? OP chce, aby plik cookie został zweryfikowany przed odpowiednią sesją w jego bazie danych. –

0

Zamiast łączenia się bezpośrednio z zasobami, użyj jakiejś formy kontrolera do wyświetlenia obrazów.

Na przykład, łącząc do "images/bob.jpg "w rzeczywistości nie wskaże zasobu, ale skrypt, który sprawdza logowanie, a jeśli się powiedzie, wysyła nagłówki image/jpeg z poprawnymi danymi.

+0

Zauważa tę technikę w swojej odpowiedzi; pyta, czy istnieje alternatywa, która nie wymaga uruchomienia skryptu dla każdego elementu treści. –

0

Właściwie nie używam Apache; Używam lighttpd, który zawiera wtyczkę, której możesz użyć do ograniczenia dostępu do folderu na podstawie tego, czy poprawny skrót zostanie przekazany w URI. Zasadniczo, twoja logika aplikacji i serwer WWW dzielą sekretną sól, która jest następnie używana do generowania skrótu z bieżącym czasem, który jest również przekazywany z hashem. Jeśli czas przypada w ciągu ostatnich 5 minut, przyznaje dostęp. Jeśli nie, lub jeśli hasz jest nieprawidłowy, oznacza to, że nie. Sprawdzam, czy w tej chwili jest podobna wtyczka do Apache.

Edit: mod_auth_token wydaje się zrobić to samo dla Apache.

+0

Niestety, to chyba wymaga zmiany adresów URL, co nie jest dla mnie rozwiązaniem. – Luke