2011-04-24 11 views
5

Actualmente estoy usando mod_rewrite para hacer una redirección internamod_rewrite: permitir redirección, pero evitar el acceso directo

RewriteCond %{REQUEST_URI} ^/pattern$ 
RewriteRUle .* file.php 

Sin embargo, me gustaría evitar el acceso directo a file.php al redirigir las peticiones a ese archivo a una página no encontrada URL .

RewriteCond %{REQUEST_URI} /file.php 
RewriteRule .* page-not-found.php 

El problema es que la segunda regla se aplica también cuando lo haga la primera redirección y, por tanto, rompe el primer redirect interno.

[Q] ¿Hay alguna manera de permitir el primer redireccionamiento pero impedir el acceso directo al archivo redirigido?

Respuesta

6

Editar: (. Que en su forma actual sin embargo, no parece funcionar para mí - se ve como la segunda regla consigue aplicar de todos modos) Inspirado por la respuesta de @ AndrewR un .htaccess única solución que funciona con una llave secreta.

Si encuentra un patrón válido, agregue una clave secreta a la cadena de consulta.

Luego, prueba esa clave secreta al decidir sobre la redirección de página.

RewriteEngine on 
Options +FollowSymlinks 

RewriteCond %{REQUEST_URI} ^/pattern$ 
RewriteRule .* /file.php?SUPER_SEKRIT_KEY [QSA] 

RewriteCond %{QUERY_STRING} !SUPER_SEKRIT_KEY 
RewriteCond %{REQUEST_URI} /file.php 
RewriteRule .* /test/page-not-found.php [L,F] 

¡Utilice una clave más compleja, por supuesto, y solo para redirecciones internas! De lo contrario, el usuario podrá agarrar la clave secreta.

+1

en lugar de la clave secreta, una variable de entorno con t La etiqueta E podría ser menos intrusiva (sin alterar el QUERY_STRING que se puede usar más adelante) – regilero

+0

@regilero ¿Puedes dar un pequeño ejemplo, por favor? – Etherealone

+0

Creo que @regilero significa algo así como "RewriteRule. * - [E = clave: SEKRITVALUE]" seguido de una prueba RewriteCond en% {ENV: clave}. Sin embargo, no puedo hacer que funcione ... –

2

Puede agregar [L] al final de la regla de reescritura, lo que significa Último, o no más procesamiento. Esto solo funcionará dentro de la configuración de Apache. No funciona en un archivo .htaccess.

RewriteEngine On 

RewriteCond %{REQUEST_URI} pattern$ 
RewriteRule .* /file.php [L] 

RewriteCond %{REQUEST_URI} file.php$ 
RewriteRule .* /page-not-found.php [L] 
+0

Esto no bloqueará el acceso a 'file.php' aunque? –

+0

Solo incluí la regla de reescritura como ejemplo. Agregué el segundo para mayor claridad. Ambos son requeridos. – AndrewR

+0

Mm, no puedo hacer que esto funcione en mi Apache 2. ¿Estás seguro de que esto puede funcionar? –

2

Una forma más sencilla de hacerlo solo con .htaccess.

Mueva su archivo.php a un nuevo directorio llamado securedir. En el directorio raíz usa este archivo .htaccess.

RewriteEngine On 
RewriteRule ^pattern$ securedir/file.php 

Impedir el acceso a cualquier cosa en securedir con esto en un archivo .htaccess allí. (O directamente de vuelta a una página diferente, si lo prefiere.)

deny from all 
+0

Gracias. ¿Qué líneas tienes, pero antes de "negar a todos" para .htaccess para entender que está relacionado con el directorio de secureir? – Max

+0

Nada más. Entra en su propio archivo .htaccess dentro de securedir. – AndrewR

7

Usando ENV:REDIRECT_STATUS variable (ver mromaine 's contribution a "Hidden features of mod_rewrite" community wiki:

RewriteCond %{REQUEST_URI} ^/pattern$ 
RewriteRule .* file.php 

# Redirect direct access to file.php 
RewriteCond %{REQUEST_URI} /file.php 
RewriteCond %{ENV:REDIRECT_STATUS} ^$ 
RewriteRule .* page-not-found.php 

Los casos de prueba:

Cada respuestas HTTP son HTTP 200.

+0

+1 para 'RewriteCond% {REQUEST_URI}/file.php' con' RewriteCond% {ENV: REDIRECT_STATUS}^$ 'esto resuelve uno para mí. ¡Gracias! – insaner

+0

¿Se almacenan los entornos por sesión de cliente? Quiero decir, ¿es seguro usarlos como arriba mientras que varias solicitudes pueden llegar concurrentemente? – Farzan

+0

Creo que las variables de entorno son por solicitud, especialmente esta ('ENV: REDIRECT_STATUS') que se completa con el proceso interno de Apache. – CDuv

Cuestiones relacionadas