PHP protège le répertoire de l’access direct à l’URL

J’ai un script ADMIN.

admin/index.php 

Toute l’activité se fait via ce fichier index.php .
Les utilisateurs se connectent avant d’accéder à la fonctionnalité du programme.
$_SESSION['user_authenticated'] est créé et défini sur true .

 admin/template/.. 

Ce dossier contient des images , des fichiers css , javascript .
Ils ne sont utilisés que dans cette ADMIN. (dans le backend uniquement)

La question:

J’ai besoin de tout le contenu du répertoire admin/template/.. pour être protégé contre un access direct .
Il ne devrait être disponible que pour les utilisateurs authentifiés.

Je suppose qu’il doit y avoir un .htaccess redirigeant les requêtes vers check_session_auth_variable.php , qui regarde si $_SESSION['user_authenticated'] est vrai ou faux et redirige vers le fichier demandé ou génère une erreur 404 ?

Je sais que la meilleure option serait de placer le répertoire en dehors de la racine Web, mais dans mon cas, je dois conserver la structure du répertoire telle quelle, sans modification.

admin / .htaccess:

 RewriteCond %{REQUEST_FILENAME} !check_auth.php RewriteCond %{REQUEST_FILENAME} -f RewriteRule .* check_auth.php?file=$0 [QSA,L] # pass everything thru php 

admin / check_auth.php:

 $file = $_GET['file']; if($_SESSION['user_authenticated']) { // please mind you need to add extra security checks here (see comments below) readfile($file); // if it's php include it. you may need to extend this code }else{ // bad auth error } 

Ok, voici ma réponse – et il est vrai que la meilleure réponse est «non». Mais les images / js / css sont relativement importantes en développement (avant de devenir publiques lorsqu’elles sont en direct) et les aperçus clients dictent que nous ne pouvons pas faire de règle Apache basée sur IP. Donc, la règle (ci-dessus, légèrement modifiée) est

 RewriteEngine On # Exclude the public and error directories from authentication RewriteRule ^(public|error)($|/) - [L] # Perform authentication via php RewriteCond %{REQUEST_FILENAME} !auth.php RewriteCond %{REQUEST_FILENAME} -f RewriteRule .* auth.php?requested_file=$0 [QSA,L] 

(parce que j’avais besoin de quelques sous-répertoires où le contenu était effectivement public, lisez: les images / css / js utilisées sur la page de connexion)

et le php pertinent est comme suit; pour

  if($authenticated){ if($extension == 'php'){ call_user_func(function(){ $file_name = func_get_arg(0); $path = getcwd(); chdir(pathinfo($file_name,PATHINFO_DIRNAME)); return include($file_name); chdir($path); }, $file_name); } else { //set cache headers so the browsers don't have to refresh all the // static content header_remove('X-Powered-By'); header_remove('Transfer-Encoding'); header_remove('Cache-Control'); header_remove('Pragma'); header_remove('Expires'); //header('Expires:'); header('Content-type: '.$mime_type); readfile($file_name); } } 

Qu’est-ce que cela fait est exécute php en utilisant call_user_func() pour arrêter la pollution de l’espace de noms, include() pour exécuter PHP et chdir() pour s’assurer que le script obtient un répertoire de travail en cours approprié.

C’est la partie “facile”; les en-têtes de contenu et le type MIME doivent être «devinés» (j’ai utilisé finfo pour les types MIME, mais il y a un bogue en 2013, et cela ne fait qu’exacerber le problème) mais même Apache ne peut pas le faire correctement à 100% …

Ensuite, supprimez les en-têtes de contrôle du cache pour les images, sinon vous serez souvent non seulement en tant que pages php …

il suffit de dire; il vous suffit de faire cela si vous avez des tuyaux épais et beaucoup de cycles de processeurs dont vous n’avez pas besoin …

J’utilise habituellement ceci

 $redi_ext = $_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI']; $php_verify = strpos($redi_ext, ".php"); if($php_verify !== false){ header('location: PAGE_NOT_FOUND_URL'); }