Usuario:ManuelRomero/ProgramacionWeb/php/Persistencia
- ===Qué es autentificarse===
- Por autentificarse vamos a entender el mecanismo por el cual el servidor web puede estar relativamente confiado en que está siendo consultado por una determinada máquina y/o persona.
- Como ejemplos de modos de autentificación, podemos visitar esta página y ver diferentes modos en los que piden autentificarse.
https://www.tractis.com/login
Contenido
- 1 Modos de autentificarse
- 2 Protocolo http vs https
- 3 Autentificación por el servidor web
- 4 Crea un fichero de usuarios
- 5 ¿Qué son las sesiones?
- 6 Documentación
Modos de autentificarse
- Contraseña y usuario.
- Almacenar el usuario en sesión (Lo veremos más adelante). Lo podríamos considerar el método tradicional y válido para la mayoría de aplicaciones que pudiéramos realizar.
- Necesitamos una base de datos dónde almacenar los datos de usuario y contraseña
- Dni digital.
- Certificados digitales de usuario.
- Autentificación basada en Tokens.
- Usando el protocolo Auth 2.0 (Lo veremos en app híbridas usando el protocolo Auth 2.0).
- Usando JSON Web Token (JWT) http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html
- Autentificación en dos pasos
- En este método de autentificar, el usuario, además de acreditarse con sus credenciales (usuario y password), se ha verificar con otro método que algún tipo de identificador que el sistema que le ha de autentificar le va a enviar.
- SMS OTP (On Time Password) donde el sistema envía un sms a su teléfono móvil que el sistema ha de conocer
- Envío de un códiog al correo electrónico. Usado por muchos sistemas como git.
- Envío de una URL al sms o al correo electrónico para acceder al sistema
- Un siste
- Autentificación basada en factores biométricos.
- Por ejemplo huella digital o lectura del iris del ojo. Muy utilizada en dispositivos móviles y acceso a espacios reservados.
1.Autentificarse a través de la cuenta de Twiter 2.Autentificarse a través de la cuenta de Facebook 3.Autentificarse a través de la cuenta de Google |
- Seguro que hay mas sistemas y seguro que muy interesantes, pero estos son los que aquí veremos.
- Nosotros en este tema usaremos el modo de contraseña y usuario. En dos temas posteriores, cuando veamos servicios web usaremos otro sistema como google; igualmente se podría usar la cuenta de facebook o twiter para identificarte, en la relación anterior hay algún enlace por si es de tu interés.
La responsabilidad de exigir una clave de acceso puede recaer sobre el servidor web (en nuestro caso apache), con los módulos de seguridad.
- En este caso restringimos el acceso a la página o sitio web.
- Otra opción habitual es tener un sitio con cierto contenido y en el sitio dar la posibilidad de identificarse / registrarse.
- A usuarios identificados se les ofrece otro contenido diferente.
Respecto a estos conceptos vamos a trabajar este tema que es el primero de tres aspectos de este tema.
Protocolo http vs https
Este es un concepto importante, diferenciar en contenidos que se envíen de forma segura (usar cifrado en el envío que es lo que se hace con https) y en el hecho que para acceder a un sitio tengan un nivel de seguridad que implique que de alguna manera te tengas que autentificar.
La seguridad del envío de datos es otro aspecto diferente del tema de la autentificación.
En seguridad entre otros aspectos tenemos:
- La autentificación mecanismos por los cuales podemos confiar en que quien se ha identificado es conocido para el sistema.
- La confidencialidad son mecanismos con los que podemos confiar en que nadie puede ver el contenidio de la información ni modificarla durante la transmisión.
Ambos mecanismos debería de trabajar conjuntamente. Por ejemplo si yo envío una contraseña para identificarse, pero con un sniffer, alguien la puede capturar y ver en claro, no conseguimos nada de seguridad.
- Para la transmisión segura se emplea el protocolo https.
- Este tema se estudia en el módulo de despliegue de aplicaciones web.
Autentificación por el servidor web
https://httpd.apache.org/docs/2.4/howto/auth.html
- Es el propio servidor http quien nos ofrece este método de autentificación.
- Este tema es un tema de sistemas, y se estudia en módulos correspondintes a despliegue o a la red y sus servicios. En este caso el servicio web.
De cualquier forma como desarrolladores, nos va a interesar y lo vamos a utilizar de dos formas:
|
- Para estos cometidos, hemos de configurar el servidor. Es importante entender cómo es la configuración de apache, analicemos y comentemos la siguiente imagen:
- Como vemos, podemos aportar parámetros de configuración de apache para un proyecto concreto incluyendo las directivas necesarias en un fichero llamado .htaccess.
- Para hacer esto, ese directorio ha de permitir su lectura. Esto implica que ese directorio (o uno del que descienda), tiene que tener activa la directiva AllowOverride, en el fichero de configuración de apache
- Por lo tanto el primer paso para realizar esta configuración es establecer dicha directiva
Verifica Que tienes dicha directiva y confirma que tienes claro en qué directorio hay que establecerla
|
- Definir los usuarios con acceso permitido.
- Se puede indicar a qué recursos tiene acceso el usuario en concreto (me refiero a qué páginas).
- Generar en cabecera http un código http 401 que es un código de acceso restringido. ##Este código hace que el usuario reciba un formulario para aportar sus credendiales.
- El navegador al recibir ese código solicita credenciales.
- El servidor recibe estas credenciales y las almacena en sus variables superglobales para futuras solicitudes.
A continuación analizaremos cada uno de estos pasos
Crear la lista de usuarios
- Usamos la herramienta htpasswd para crear un fichero con los usuarios y sus contraseñas
http://httpd.apache.org/docs/2.4/es/howto/auth.html
- En caso de no tener la herramienta instalada debemos hacer la instalación de las herramientas o utilidades de apache escribiendo:
sudo apt-get install apache2-utils
- Este comando tiene una serie de opciones que podemos ver en línea de comandos sin mas que escribir su nombre.
Usage: htpasswd [-cmdpsD] passwordfile username htpasswd -b[cmdpsD] passwordfile username password htpasswd -n[mdps] username htpasswd -nb[mdps] username password -c Create a new file. -n Don\'t update file; display results on stdout. -m Force MD5 encryption of the password (default). -d Force CRYPT encryption of the password. -p Do not encrypt the password (plaintext). -s Force SHA encryption of the password. -b Use the password from the command line rather than prompting for it. -D Delete the specified user. On other systems than Windows, NetWare and TPF the '-p' flag will probably not work. The SHA algorithm does not use a salt and is less secure than the MD5 algorithm.
- Es importante la opción -c para crear el fichero. Recuerda usarla sólo la primera vez; cuando la usas se crea el fichero, y si ya existiera se elimina el contenido del fichero y se crea de nuevo.
- Para incorporar nuevos usuarios se escribe sin opción y se añade el nombre de los usuario
- Por seguridad es importante añadir el fichero en una ubicación fuera del directorio documentRoot del servidor web.
Ficheros de usuarios | |
---|---|
|
Indicar los recursos restringidos : .htaccess
- Para este cometido, apache nos permite usar el famoso fichero .htaccess que a continuación vamos a explicar.
- Para habilitar el uso de este fichero debemos indicarle al servidor web que vamos a utilizarlo. Esto se especifica en la directiva AllowOverride
- Para más información ver
http://www.bdat.net/documentos/apache/x367.html
Y la oficial (siempre la mejor).
http://httpd.apache.org/docs/2.4/es/mod/core.html#allowoverride
- En nuestro caso tenemos que poner el valor AuthConfig o bien All
- Una vez que hemos hecho esto, cada vez que vaya a coger un fichero de un determinado directorio, antes de entregarlo, verificará que si existe un fichero .htaccess en ese directorio, en cuyo caso pedirá credenciales.
- Para indicar los recursos restringidos usaremos las siguientes directivas (Este será el contenido del fichero .htaccess
- AuthName Nombre de dominio de la authentificación.
- AuthType Tipo de autentificación, pudiendo ser Basic y más segura Digest, donde se ustilizan una cadena 'realm' y dos valores únicos generados por el servidor con por ejemplo llamados nonce y opaque.
md5(uniqid())
- AuthUserFile Ruta del fichero de los usuarios con permiso.
- AuthGroupFile Ruta del fichero de los usuarios con permiso.
- Require valid-user o usuarios concretos de la lista que sí que tendrán acceso al recursos si se acreditan correctamente. group o grupos concretos a validar
|
- En el caso de querer crear un grupo se haría de la siguiente manera
- Primero creamos un grupo en un fichero
grupo1: user1 user2 user3
- guardamos esta información en un fichero, por ejemplo
/home/manuel/credenciales/grupoAdmin
- Por supuesto estos usuarios deben de ser incluidos en el fichero de password, con el comando htpasswd
- Y ahora especificamos el grupo en las restricciones de acceso en el fichero .htaccess con la directiva AuthUserFile para especificar el grupo y en la directiva RRequire' especificamos group y nombre de grupo.
AuthType Basic AuthName Restricción de grupos AuthUserFile /home/manuel/credenciales/passwords AuthGroupFile /home/manuel/credenciales/grupoAdmin Require group
a2enmod authz_groupfile
- En este caso la validación la hace el servidor apache. Es decir, si se ejecuta el fichero solicitado, es porque apache ya ha validado.
- Si se validó previamente, apache utiliza cookies de sesión, que desde php no podemos modificar ni borrar, por lo que si volvemos a entrar en la página ya no nos pedirá validación.
- Observa el ejemplo anterior en el cual se ha creado una página para eliminar el usuario dejando solo acceso a un usuario que no existe y así forzamos que se borre el anteriormente registrado.
PHP accediendo a información http
- Ahora viene la parte que realmente nos interesa a nosotros/as, qué es usar esto, dentro de nuestro código php.
- En este caso no vamos a necesitar el fichero .htaccess, ya que no queremos que apache realice la validación, queremos hacerla dentro de nuestro script.
- Desde el código de php podemos acceder a la información facilitada por el servidor.
- Tenemos que conseguir hacer que si se validó correctamente ejecutemos el script completo y si no se ha validado que se le entregue un formulario de validación que entrega apache cuando queremos validar.
- Para ello vamos a usar la función header para crear cabeceras y entregar un página para autentificarse en caso de que no se haya autentificado (el formulario), y si se ha identificado cogeremos las credenciales facilitadas y las verificaremos.
- Para recoger las credenciales del formulario, accederemos a la matriz asociativa $_SERVER
Concretamente los índices:
|
Usar función header para la autentificación
- La referencia de la función header Sirve para crear cabeceras de la página solicitada
http://es.php.net/manual/es/function.header.php
Vamos a usarla para unas acciones concretas.
- Modificar el texto de error
En este caso no vamos a usar el fichero .htaccess. Cuando accedemos a una página y no nos hemos identificado aparece un error 401. Nosotros vamos a solicitar una autentifiCación tipo basic. < br/> Para ello especificamos la cabecera WWW-Authenticate.Ademas de especificar el modo de autentificación ponemos el mensaje que verá el usuario:
header('WWW-Authenticate: Basic Realm="Página de acceso restringido. Necesitas credenciales"');
- Para no mostrar la página solicitada se envía un código 401, lo que provoca que se solicite un usuario y contraseña antes de visualizar el resto de la página. El código quedaría:
header('HTTP/1.0 401 Unauthorized');
El código completo quedaría:
<?php if (!isset($_SERVER['PHP_AUTH_USER'])) { header('WWW-Authenticate: Basic Realm="Contenido restringido"'); header('HTTP/1.0 401 Unauthorized'); echo "Usuario no reconocido!"; exit; } ?>
- Ahora debemos poder especificar cuál va a ser el usuario esperado en esta página. Por ejemplo en la página anterior insertamos un usuario cualquiera y una password cualquiera entraremos ya que no comparamos con ningún valor.
<?php echo"Nombre de usuario: ".$_SERVER['PHP_AUTH_USER'] ."<br />"; echo"Contraseña: ".$_SERVER['PHP_AUTH_PW'] ."<br />"; ?>
Verificar el usuario y contraseña
Con el siguiente código verificaríamos el usuario y contraseña usando el modo de header.
<?php if ($_SERVER['PHP_AUTH_USER']!='manolo' || $_SERVER['PHP_AUTH_PW']!='passManolo.') { header('WWW-Authenticate: Basic Realm="Contenido restringido"'); header('HTTP/1.0 401 Unauthorized'); echo "Usuario no reconocido!"; exit; } ?>
- Esto nos podría servir, puesto que el código no se envía al cliente, y él nunca podría ver la password, ni el usuario. No obstante, siempre será una opción más segura, y más versátil tener el usuario almacenado en una base de datos que ya veremos más adelante cuando veamos bases de datos.
- ===Qué es una Cookie===
- Una cookie es una pequeña cantidad de datos almacenada por el navegador del usuario cuando solicita una página a un servidor. *Básicamente consiste en una cantidad de información que almacena preferencias de un usuario.
Una Cookie' es un fichero que se almacena en el cliente y guarda información de ese cliente en referencia a una determinada sitio web. |
Una vez que el cliente almacena ese valor, la próxima vez que ese cliente (una ip y un navegador), haga una solicitud a ese servidor, le enviará también todas las cookies que tenga de ese servidor.
En parte se podría pensar que con esta técnica podemos suplir la característica de que http es un protocolo sin estado (Insistir en que esto es una característica del protocolo, no una limitación), y mantener información después de la visita a un sitio web.
http://www.agpd.es/portalwebAGPD/canaldocumentacion/publicaciones/common/Guias/Guia_Cookies.pdf |
- En general no se debe de abusar de ellas; hay que tener en cuenta que en muchos las pueden tener deshabilitadas y esto puede impedir que nuestra aplicación web se ejecute de forma eficiente o incluso correcta. Por ello no debería de ocurrir que una aplicación web dependiera de los valores de cookies para funcionar de forma correcta.
Ciclo de vida de la cookie
- Veamos el proceso detallado
|
|
Crear una coockie
- Para ello usaremos la función setcookie(...)
setcookie(Nombre_cookie,Valor_Coookie, tiempo_vida);
- En esta función puede recibir hasta 7 parámetros, (sólo el primero es obligatorio).
http://es.php.net/manual/es/function.setcookie.php
- Es habitual usar los tres primeros que serían
- Nombre de la cookie
- Valor que almacenamos en ella
- Tiempo de expiración: es un entero en segundos. Si no se especifica, la cookie termiará junto a esta sesión.
- Por ejemplo si quieremos almacenar el usuario y que tenga un tiempo de duración de 1 hora
setcookie("usuario", $_SERVER['PHP_AUTH_USER'], time()+3600);
- Importante el envío de cookies al cliente ha de hacerse antes de que se escriba nada en html, igual que las funciones header.
Recuperar la cookie
- El proceso de recuperación de la información que almacena una cookie es muy simple.
- Cuando accedes a un sitio web, el navegador (cliente), le envía de forma automática todo el contenido de las cookies que almacene relativas a ese sitio en concreto (servidor).
- Desde PHP se puede acceder a esta información por medio del array $_COOKIE.
$usuario = $_COOKIE[nombre_cookie];
- Para recuperar los datos anteriores
$usuario = $_COOKIE['usuario'];
Borrar una cookie
- Para borrar la cookie usamos la función setcookie con un tiempo negativo
<?php // Ponemos un tiempo de expiración negativo setcookie("user", "", time()-3600); ?>
Cookies con información de visitas
|
<?php $expire = time()+60*60*24*30 //La coockie durará un mes setcookie("user", "Alex Porter", $expire); ?>
<?php $expire = =; //La coockie durará lo que dure la sesión setcookie("user", "Alex Porter", $expire); ?>
<?php // Ver una cookie concreta echo $_COOKIE["user"]; // Para ver todas las cookies print_r($_COOKIE); ?>
<?php // Ponemos un tiempo negativo setcookie("user", "", time()-3600); ?> |
¿Qué son las sesiones?
- Es otro método para hacer que variables estén disponibles en múltiples páginas
- A diferencia de las cookies, las variables de sesión se almacenan en el servidor
- Tienen un tiempo limitado de existencia.
- Para identificar al usuario que generó las variables de sesión, el servidor genera una clave única que es enviada al navegador y almacenada en una cookie.
- Luego, cada vez que el navegador solicita otra página al mismo sitio, envía esta cookie (clave única) con la cual el servidor identifica de qué navegador proviene la petición y puede rescatar de un archivo de texto las variables de sesión que se han creado.
- Cuando han pasado 20 minutos sin peticiones por parte de un cliente (navegador) las variables de sesión son eliminadas automáticamente (se puede configurar el entorno de PHP para variar este tiempo).
- Una variable de sesión es más segura que una cookie ya que se almacena en el servidor.
- No tiene que estar enviándose continuamente como sucede con las cookies.
- Cuando el navegador del cliente está configurado para desactivar las cookies las variables de sesión, tienen forma de funcionar (enviando la clave como parámetro en cada hipervínculo).
- Desventaja: ocupa espacio en el servidor.
SSID de la sesión
- Existen dos maneras de mantener el SSID de la sesión
- Utilizando cookies, tema ya visto.
- Propagando el SID en un parámetro de la URL. El SID se añade como una parte más de la URL, de la forma:
http://www.misitioweb.com/tienda/listado.php&PHPSESSID=34534fg4ffg34ty
- En el ejemplo anterior, el SID es el valor del parámetro PHPSESSID.
- En php todas estas acciones se realizan de forma transparente para el programador, es decir, como desarrolladores podemos directamente utilizar las sesiones en php sin necesidad de tener que transmitir el SSID. Directemnte php nos ofrece supervariables y funciones para gestionarlo.
Configuración
- Existen una serie de directivas para configurar las sesiones, que conviene conocer
- Estas se pueden consultar viendo phpinfo(), y modificar en el fichero de configuración de php, php.ini
- Para ver todas las directivas http://es.php.net/manual/es/session.configuration.php
- session.use_cookies
- Indica si se deben usar cookies (1) o propagación en la URL (0) para almacenar el SID.
- session.use_only_cookies
- Se debe activar (1) cuando utilizas cookies para almacenar los SID, y además no quieres que se reconozcan los SID que se puedan pasar como parte de la URL (este método se puede usar para usurpar el identificador de otro usuario).
- session.save_handler
- Se utiliza para indicar a PHP cómo debe almacenar los datos de la sesión del usuario. Existen cuatro opciones: en ficheros (files), en memoria (mm), en una base de datos SQLite (sqlite) o utilizando para ello funciones que debe definir el programador (user). El valor por defecto (files) funcionará sin problemas en la mayoría de los casos.
- session.name
- Determina el nombre de la cookie que se utilizará para guardar el SID. Su valor por defecto es PHPSESSID.
- session.auto_start
- Su valor por defecto es 0, y en este caso deberás usar la función session_start para gestionar el inicio de las sesiones. Si usas sesiones en el sitio web, puede ser buena idea cambiar su valor a 1 para que PHP active de forma automática el manejo de sesiones.
- session.cookie_lifetime
- Si utilizas la URL para propagar el SID, éste se perderá cuando cierres tu navegador. Sin embargo, si utilizas cookies, el SID se mantendrá mientras no se destruya la cookie. En su valor por defecto (0), las cookies se destruyen cuando se cierra el navegador. Si quieres que se mantenga el SID durante más tiempo, debes indicar en esta directiva ese tiempo en segundos.
- session.gc_maxlifetime
- Indica el tiempo en segundos que se debe mantener activa la sesión, aunque no haya ninguna actividad por parte del usuario. Su valor por defecto es 1440. Es decir, pasados 24 minutos desde la última actividad por parte del usuario, se cierra su sesión automáticamente.
Creando la sesión
- En función de como esté configurado la directiva session.auto_start
- Si esta activada, la sesión comienza automáticamente al conectarse a un sitio
- Si no está activada la iniciaremos con la funcion session_start();
Tip: Una vez creada la sesión podemos almacenar/consultar información de la misma consultando la variable superglobal $_SESSION
Programa de visitas con sesiones
Tip: Cuando se hace un cambio de estado (login, cambio de permisos, ...): regenerar id.session_regenerate_id()
Eliminando la sesion
- Se puede configurar para que de forma automática se eliminen los datos de una sesión pasados un determinado tiempo
- También podemos actuar directamente sobre una sesión eliminando información
- session_unset.
- Elimina las variables almacenadas en la sesión actual, pero no elimina la información de la sesión del dispositivo de almacenamiento usado.
- session_destroy.
Elimina completamente la información de la sesión del dispositivo de almacenamiento.