sábado, 26 de enero de 2013

Problemas con el Apache .htaccess mod_rewrite

Mi .htaccess no funciona

Dilema.

Resumen corto para los entendidos:

1. Que la directiva AllowOverride no este configurada a "None" en httpd.conf.
2. Que el mod_rewrite este habilitado en httpd.conf.
3. Recuerda hacer pruebas con previa limpieza de la cache del navegador.

Primero, qué es y para qué sirve un .htaccess

Un .htaccess es un archivo de configuración en modo texto que solo funciona cuando un servidor web esta siendo atendido por un servicio de Apache.

Tiene muchos usos, dividos basicamente en dos categorías:

1) Para configurar el acceso a los archivos dentro de un directorio de un website. (para que un visitante no pueda visualizar archivos delicados que estan alojados dentro del website, por ejemplo).

2) Para controlar otros servicios de apache entre ellos mod_rewrite, el cual es el objeto de este tema y al cual me enfocaré.

(si..hay mas usos, pero al iniciado no le vamos a lanzar todo de una vez verdad ?)

El principio:  Apache

Apache es un servidor web que funciona en Linux o en Windows, es un sistema que permite que un computador pueda ofrecer servicios web.  Toda la información reelevante esta aqui: http://httpd.apache.org/

El módulo de Apache: mod_rewrite

http://httpd.apache.org/docs/current/mod/mod_rewrite.html

Es un módulo de Apache que presta servicios al website basados en "sobreescribir" (mod_rewrite) la url que nosotros hemos introducido usando una expresion regular:

Con un ejemplo:

Queremos que cuando un usuario de la web ingrese a:

http://www.miwebsite.com/articulos/pelota/azul/

entonces que en realidad acceda a :

http://www.miwebsite.com/index.php?r=/catalogo/buscar&name=pelota&color=azul

Si te has dado cuenta la segunda URL es espantosa pero seguramente es la URL que va a funcionar en el sistema que tenemos hecho.
La primera URL es la que se llama "Friendly Url", es aquella mejor apetecida por los buscadores y demás instrumentos, incluso humanos.

Esta sobreescritura de URL es llevada a cabo por el modulo mod_rewrite del servicio apache mediante la configuración indicada en el archivo .htaccess localizado en la raiz de tu sitio web, siempre y cuando:
La directiva AllowOverride de apache no este configurada en modo "None".


http://httpd.apache.org/docs/current/mod/mod_rewrite.html

Habilitar el .htaccess en Apache

Antes que nada, hay que asegurarse que Apache va a habilitar los .htaccess, de otro modo no importa que basura pongas allí, esta no va a funcionar. Para habilitar el .htaccess sobre Apache primero hay que editar el archivo httpd.conf y establecer allí la directiva AllowOverride a algun valor distinto a None.

Mas información de la directiva aqui:

http://httpd.apache.org/docs/2.2/mod/core.html#allowoverride

<Directory /mi/sitio/web/mi/ruta/>
   ..otras directivas aqui
   AllowOverride All
</Directory>


Lo que aquí ocurre es que AllowOverride All admite que tu puedas "sobreescribir" (override) las directivas de acceso al directorio donde tu estas alojando tu sitio web. De otro modo, cuando tu generes un archivo .htaccess en tu sitio web este será ignorado por completo, no importa si el modulo de apache mod_rewrite este o no habiliado.
Debes comprender que el archivo .htaccess es un archivo de Apache, y que el modulo mod_rewrite es simplemente un subproducto que usa a Apache, por consecuencia usa los servicios de .htaccess que este le provee para leer desde allí lo que mod_rewrite necesite para funcionar, por tanto si no puedes darle valores a .htaccess debido a la negativa de la directiva mencionada entonces mod_rewrite no va a funcionar.
Y qué es httpd.conf ? es el archivo de configuración básico del servidor web de Apache. Muy seguramente en un entorno de hospedaje de la calle esto no será necesario porque el webmaster de esa empresa ya lo habilitó, deberá hacerlo, de otro modo nadie le va a hospedar nada allí porque su servicio no servirá para casi nadie.

Habilitar el modulo mod_rewrite en Apache

El módulo mod_rewrite debe ser habilitado por el webmaster del servicio de hospedaje, casi todos lo admiten, algunos requieren que tu explicitamente lo invoques (caso 1and1), como mencione mas arriba la información detallada del modulo esta aqui:

http://httpd.apache.org/docs/current/mod/mod_rewrite.html

Cómo saber si el modulo mod_write esta instalado en tu hospedaje o servidor web:

1. crea un archivo llamado info.php en alguna parte de tu website, con el siguiente contenido:
<?php echo phpinfo(); ?>

2. accede a el desde el browser: http://localhost/tuwebsite/info.php

3. Buscarás el texto "mod_rewrite" (con el buscador del browser), deberá aparecer en:

Loaded Modulescore mod_log_config mod_logio prefork http_core mod_so mod_alias mod_auth_basic mod_authn_file mod_authz_default mod_authz_groupfile mod_authz_host mod_authz_user mod_autoindex mod_cgi mod_deflate mod_dir mod_env mod_mime mod_negotiation mod_php5 mod_reqtimeout mod_rewrite mod_setenvif mod_status


Si aparece el texto "mod_rewrite" es porque esta instalado en el Apache. Si no aparece, hay que habilitarlo en el archivo de configuración del apache, de esta forma:

Habilitar mod_rewrite en Apache

Caso Linux:

La instalación de Linux comunmente trae el modulo rewrite, pero deshabilitado.  Para habilitarlo hay que ingresar al servidor con permisos de root y crear un enlace simbolico al modulo, luego reiniciar el servicio apache, en resumidas cuentas se hace esto:

# su
# password ****
# ls /etc/apache2/mods-available/rewrite.load

  ...como resultado veran que al listar aparecera el modulo:
# rewrite.load

Hasta aqui confirmamos que el modulo esta disponible, ahora para ver si esta instalado (importante: se busca en "mods-enabled")

ls -l /etc/apache2/mods-enabled/rewrite.load

Si no esta instalado (porque no aparece al listarlo con el comando anterior) entonces hay que crear un enlace simbolico:

cd /etc/apache2/mods-enabled   #bajo root
ln -s /etc/apache2/mods-available/rewrite.load rewrite.load #crear enlace sim
/etc/init.d/apache2 restart   #reiniciar apache



En el caso de Windows:
es mas simple, se edita el archivo:
c:/archivos de programa/apache2/bin/httpd.conf y se habilita la linea que ya viene escrita pero con un # por delante, ese # es indicador de que la linea esta comentada por tanto no va a funcionar, al quitarla va a funcionar.

En ambos casos hay que reiniciar el servicio apache.  Vuelve a cargar el archivo info.php y debería aparecer el texto mod_rewrite indicado en la figura de arriba.

Crear un archivo .htaccess

En un sitio web cualquier que tengas, crea un archivo llamado ".htaccess",  verifica que en el caso de windows no se este creando en cambio un archivo ".htaccess.txt" porque no va a servir. Igualmente es mejor hacerlo por consola debido a que algunos editores de texto consideran a los archivos que empiezan por "." como archivos de sistema y pueden haber problemas.

En el caso de Windows no podrás crear el archivo desde el "explorador de archivos" (file manager), debido al "." que esta al inicio de ".htaccess", hazlo por consola: "cmd.exe".

Probar un archivo .htaccess en el website

Supongamos que tenemos el sitio web: http://localhost/miweb con SOLO UN archivo dentro (solo texto1.html, nada mas, sin ningun index.html )

http://localhost/miweb/texto1.html  (que dira "hola1")

Creamos un .htaccess (en linux):

cd /home/christian/www/miweb/
$ cat > .htaccess
(escribe algo:)  # comentario de prueba
(presiona control+Z)

eso va a crear un archivo .htaccess con una linea comentada que dice: "#comentario de prueba". hazlo por otra via si es necesario, pero debe llamarse ".htaccess".

Ahora navega a: http://localhost/miweb/texto1.html no debe haber ningun fallo, debe decir: "hola 1"

Ok no hay nada malo, podemos seguir con las pruebas.

Edita el archivo .htaccess y agreguemosle una regla de sobreescritura para que al escribir:
http://localhost/miweb/index.html entonces en realidad nos devuelva el contenido de "texto1.html" tal como si hubiesemos navegado directamente sobre "texto1.html", al navegar a "index.html" dirá "hola 1", considerando que "index.html" no existe..!
IMPORTANTE:
index.html "no existe" en estas pruebas, lo virtualizaremos usando una regla usando a mod_rewrite, de modo que el visitante "crea que existe" pero en realidad no y en cambio estará viendo el contenido de otro archivo.

Escribe lo siguiente dentro del ".htaccess":


RewriteEngine On     # esto le dice a apache que active a mod_rewrite para este website
RewriteRule ^index.html$ texto1.html [L]      # es es una regla de sobreescritura

Si esta funcionando, entonces al ingresar a:  http://localhost/miweb/index.html dira "hola 1"


Que sigue

Mod_rewrite es muy complejo y completo, explicarlo aqui se va del alcance del documento, por tanto una vez iniciado estes podrás seguir tu curso y ahondar mas en esta rama.

Debes aprender ahora sobre "expresiones regulares", ya que mod_rewrite esta basado en esta tecnología, cuando puse "^index.html$" en realidad es una "expresion regular" (regexp como se le conoce) la cual le dice a apache que "donde diga -index.html- entonces ahora...".

Lo que basicamente hace mod_rewrite es verificar si una URL hace "match" con alguna de las reglas, para entonces proceder con la acción para esa regla.

acerca de expresiones regulares en yii framework
http://es.wikipedia.org/wiki/RegExp
http://httpd.apache.org/docs/current/mod/mod_rewrite.html
http://httpd.apache.org/docs/2.2/mod/core.html#allowoverride

Suerte, camino largo por delante.

19 comentarios:

  1. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  2. Hola como estas?, muy bueno el tuto! muy sencillo.. lo segui paso a paso, pero me tira esto:
    ___________________________________________________
    Acceso prohibido!
    Usted no tiene permiso de accesar al objeto solicitado. El objeto está protegido contra lectura, o no puede ser leido por el servidor.
    Si usted cree que esto es un error del servidor, por favor comuníqueselo al administrador del portal.
    Error 403
    localhost
    Apache/2.4.3 (Win32) OpenSSL/1.0.1c PHP/5.4.7
    ________________________________________________________

    Tenes idea como lo resuelvo?
    Saludos!

    ResponderEliminar
    Respuestas
    1. Ya lo resolvi!
      Tenia que reiniciar el Apache nada mas!

      Eliminar
    2. que bueno, pero ya eso es otro tema, se te indica que "el objeto esta protegido contra lectura", lo cual puede indicar un fallo de permisos en el archivo .htaccess, no basta con cambiar los permisos, hay que reiniciar el servicio para que lea el nuevo permiso de archivo.

      Eliminar
  3. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  4. Excelente explicación!!, me a funcionado como debería!!, gracias hermano, saludos!

    ResponderEliminar
  5. Muchas gracias por la información.

    depedros.com

    ResponderEliminar
  6. Muchas gracias por la información me sirvio bastante, varias horas reinstalando el framework en vano.

    ResponderEliminar
  7. Hola. ¿ésta técnica se puede utilizar en blogger? Es decir, ¿se puede re-escribir las URL de los posts de blogger con Apache? Si no, ¿existe alguna forma de hacerlo?
    Saludos.

    ResponderEliminar
    Respuestas
    1. yo creo que no. a menos que blogger te de acceso a manipular las reglas. pero de verdad creo que por asuntos de seguridad ellos no van a admitir que tu manipules su sistema de reglas, así igualmente no creo que usen apache quizá en cambio otro mecanismo de reglas.

      igualmente, puedo estar equivocado.

      Eliminar
    2. Eché un vistazo a otras publicaciones en otros sitios y me parece que no es posible. Gracias igual por tu respuesta.

      Eliminar
  8. Me gustaría saber, que precauciones de seguridad en el servidor se debe tener en cuenta al hacer este cambio...

    ResponderEliminar
  9. He pasado de la versión online de una web a una copia en localhost pero no logro que funcione. Solo se ve la homepage, si accedo a algún link con SEO habilitado recibo un mensaje de error 404. Si elimino el .htaccess hace lo mismo. Tengo el mod_rewrite funcionando y reinicio el apache tras cada cambio, pero no encuentro la manera.
    Puede ser que el htaccess online tenga que ser diferente al de un localhost?

    ResponderEliminar
  10. Gran post. El "resumen para los entendidos" está muy bien con una excepción: Pareciera decir "No funciona por lo siguiente" en vez de "La solución es la siguiente". Tuve que leer todo el post para saberlo, de resto, perfecto. Muchas gracias.

    ResponderEliminar
  11. Muchas gracias, excelente tuto, muy claro!

    ResponderEliminar
  12. Buen tutorial, me fue de gran ayuda con un problema que tenía desde hace buen rato, gracias.
    Saludos.

    ResponderEliminar
  13. Genial tu post! De tosas formas tengo un problema y no puedo arreglarlo. En los link me aparece http://miempresa.com/sobre-nosotros/#.VsOzKvnhCHs
    Como saco lo ultimo (#.VsOzKvnhCHs)? no debería estar, tengo puesto nombre de entrada en ajustes-enlaces permanentes, y al crear paginas me sale bien el enlace permanente, pero luego al cargar todo en la web me sale asi en todas las paginas.
    Muchas gracias por tu tiempo!

    ResponderEliminar
  14. Gracias me sirvio mucho , no lo lei todo simplemente encontre la solucion en la primera linea asi que nada , lo guardare , htacces es importante saberlo y este post se ve muy interesante.

    Gracias por tomarte el trabajo de compartir

    ResponderEliminar