HTTP Instalación de seguridad en una página usando MySQL y PHP. HTTP Instalación de seguridad en una página usando MySQL y PHP Código fuente del script PHP
¡Buen dia amigos! Echemos un vistazo al registro de usuarios en PHP. Primero, definamos las condiciones para nuestro registro de usuario:
- La contraseña se cifra mediante un algoritmo. MD5
- La contraseña será "sal"
- Comprobación de inicio de sesión ocupado
- Activación de usuario por carta.
- Registro y almacenamiento de datos en SGBD MySQL
Para escribir este script, necesitamos entender qué es el registro de usuario. El registro de usuario está obteniendo datos usuario real, procesamiento y almacenamiento de datos.
si explicas en palabras simples entonces el registro es solo un registro y almacenamiento de ciertos datos mediante los cuales podemos autorizar al usuario en nuestro caso: este es el inicio de sesión y la contraseña.
Autorización: otorgar a una determinada persona o grupo de personas los derechos para realizar ciertas acciones, así como el proceso de verificación de estos derechos al intentar realizar estas acciones. En pocas palabras, con la ayuda de la autorización, podemos restringir el acceso a un contenido particular en nuestro sitio.
Echemos un vistazo a la estructura del directorio del script para implementar nuestro inicio de sesión con autorización. Necesitamos dividir los guiones en partes lógicas. Colocamos los módulos de registro y autorización en un directorio separado. También colocaremos la conexión de la base de datos en directorios separados. mysql, archivo con funciones personalizadas, archivo de estilo CSS y nuestra plantilla HTML. Esta estructura le permite navegar rápidamente a través de scripts. Imagina que tienes un sitio grande con un montón de módulos, etc. y si no hay orden, será muy difícil encontrar algo en tal desorden.
Dado que almacenaremos todos los datos en SGBD MySQL, luego creemos una pequeña tabla en la que almacenaremos los datos de registro.
Primero necesitas crear una tabla en la base de datos. Llamemos a la mesa bez_reg Dónde bez es el prefijo de la tabla, y registro nombre de la tabla.
Estructura de la mesa: bez_reg
-- -- Estructura de la tabla `bez_reg` -- CREAR TABLA SI NO EXISTE `bez_reg` (`id` int(11) NOT NULL AUTO_INCREMENT, `login` varchar(200) NOT NULL, `pass` varchar(32) NOT NULL , `salt` varchar(32) NOT NULL, `active_hex` varchar(32) NOT NULL, `status` int(1) NOT NULL, PRIMARY KEY (`id`)) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;Ahora vamos a crear los scripts principales para seguir trabajando.
ARCHIVO ÍNDICE.PHP
ARCHIVO CONFIG.PHP
!defined("BEZ_KEY")) { header("HTTP/1.1 404 Not Found"); exit(file_get_contents("./404.html")); } //Адрес базы данных define("BEZ_DBSERVER","localhost"); //Логин БД define("BEZ_DBUSER",""); //Пароль БД define("BEZ_DBPASSWORD",""); //БД define("BEZ_DATABASE",""); //Префикс БД define("BEZ_DBPREFIX","bez_"); //Errors define("BEZ_ERROR_CONNECT","Немогу соеденится с БД"); //Errors define("BEZ_NO_DB_SELECT","Данная БД отсутствует на сервере"); //Адрес хоста сайта define("BEZ_HOST","http://". $_SERVER["HTTP_HOST"] ..ru>"); ?>
Archivo 404.HTML
error 404 |
Hubo un error 404 en la página. |
Devolver |
Archivo BD.PHP
!defined("BEZ_KEY")) { header("HTTP/1.1 404 Not Found"); exit(file_get_contents("./../404.html")); } //Соединение с БД MySQL $db_connect = mysql_connect(BEZ_DBSERVER, BEZ_DBUSER, BEZ_DBPASSWORD) or die(BEZ_ERROR_CONNECT); define("BEZ_CONNECT", $db_connect); mysql_select_db(BEZ_DATABASE, BEZ_CONNECT)or die(BEZ_NO_DB_SELECT); //Устанавливаем кодировку UTF8 mysql_query ("SET NAMES utf8"); mysql_query ("set character_set_client="utf8""); mysql_query ("set character_set_results="utf8""); mysql_query ("set collation_connection="utf8_general_ci""); ?>
ARCHIVO ÍNDICE.HTML
ARCHIVO FUNCIÓN.PHP
!defined("BEZ_KEY")) { header("HTTP/1.1 404 Not Found"); exit(file_get_contents("./../404.html")); } /**Функция экранирования вносимых данных *@param array $data */ function escape_str($data) { if(is_array($data)) { if(get_magic_quotes_gpc()) $strip_data = array_map("stripslashes", $data); $result = array_map("mysql_real_escape_string", $strip_data); return $result; } else { if(get_magic_quotes_gpc()) $data = stripslashes($data); $result = mysql_real_escape_string($data); return $result; } } /**Отпровляем сообщение на почту * @param string $to * @param string $from * @param string $title * @param string $message */ function sendMessageMail($to, $from, $title, $message) { //Адресат с отправителем //$to = $to; //$from = $from; //Формируем заголовок письма $subject = $title; $subject = "=?utf-8?b?". base64_encode($subject) ."?="; //Формируем заголовки для почтового сервера $headers = "Content-type: text/html; charset=\"utf-8\"\r\n"; $headers .= "From: ". $from ."\r\n"; $headers .= "MIME-Version: 1.0\r\n"; $headers .= "Date: ". date("D, d M Y h:i:s O") ."\r\n"; //Отправляем данные на ящик админа сайта if(!mail($to, $subject, $message, $headers)) return "Ошибка отправки письма!"; else return true; } /**функция вывода ошибок * @param array $data */ function showErrorMessage($data) { $err = "
- "."\n"; if(is_array($data)) ( foreach($data as $val) $err .= "
- ".$val." "."\n"; ) else $err .= "
- ".$datos". "."\n"; $error .= "
Comencemos a escribir el registro. Para empezar, necesitaremos hacer una plantilla de formulario de registro para que el usuario pueda introducir sus datos para su tratamiento. A continuación, necesitaremos escribir el propio controlador de formulario, que verificará la exactitud de los datos ingresados por el usuario. Después de que los datos se verifiquen con éxito, los escribimos en nuestra base de datos y enviamos un correo electrónico al usuario para activar su cuenta.
ARCHIVO REG.PHP
!defined("BEZ_KEY")) { header("HTTP/1.1 404 Not Found"); exit(file_get_contents("./../../404.html")); } //Выводим сообщение об удачной регистрации if(isset($_GET["status"]) and $_GET["status"] == "ok") echo "¡Se ha registrado exitosamente! Por favor activa tu cuenta!!"; //Active la cuenta if(isset($_GET["key"])) ( //Revise la clave $sql = "SELECT * FROM `". BEZ_DBPREFIX ."reg` WHERE `active_hex` = "". escape_str ( $_GET["key"]) ."""; $res = mysqlQuery($sql); if(mysql_num_rows($res) == 0) $err = "¡La clave de activación no es válida!"; //Comprobar errores y mostrar al usuario if(count($err) > 0) echo showErrorMessage($err); else (//Obtener la dirección del usuario $row = mysql_fetch_assoc($res); $email = $row["login"]; //Activar la cuenta usuario $sql = "UPDATE `".BEZ_DBPREFIX ."reg` SET `status` = 1 WHERE `login` = "".$email ."""; $res = mysqlQuery($sql); / /Enviar correo electrónico de activación $title = "Su cuenta en http://sitio web se ha activado con éxito"; $message = "Поздравляю Вас, Ваш аккаунт на http://сайт успешно активирован"; sendMessageMail($email, BEZ_MAIL_AUTOR, $title, $message); /*Перенаправляем пользователя на нужную нам страницу*/ header("Location:". BEZ_HOST ."less/reg/?mode=reg&active=ok"); exit; } } /*Если нажата кнопка на регистрацию, начинаем проверку*/ if(isset($_POST["submit"])) { //Утюжим пришедшие данные if(empty($_POST["email"])) $err = "Поле Email не может быть пустым!"; else { if(!preg_match("/^+@(+\.)+{2,6}$/i", $_POST["email"])) $err = "Не правильно введен E-mail"."\n"; } if(empty($_POST["pass"])) $err = "Поле Пароль не может быть пустым"; if(empty($_POST["pass2"])) $err = "Поле Подтверждения пароля не может быть пустым"; //Проверяем наличие ошибок и выводим пользователю if(count($err) > 0) echo showErrorMessage($err); else { /*Продолжаем проверять введеные данные Проверяем на совподение пароли*/ if($_POST["pass"] != $_POST["pass2"]) $err = "Пароли не совподают"; //Проверяем наличие ошибок и выводим пользователю if(count($err) > 0) echo showErrorMessage($err); else { /*Проверяем существует ли у нас такой пользователь в БД*/ $sql = "SELECT `login` FROM `". BEZ_DBPREFIX ."reg` WHERE `login` = "". escape_str($_POST["email"]) ."""; $res = mysqlQuery($sql); if(mysql_num_rows($res) > 0) $err = "К сожалению Логин: !} ". $_POST["correo electrónico"] ." ocupado!"; //Buscar errores y mostrar al usuario if(count($err) > 0) echo showErrorMessage($err); else ( //Obtener el HASH de la sal $salt = salt(); // Saltar la contraseña $pass = md5(md5($_POST["pass"]).$salt); /*Si todo va bien, escribir datos en la base de datos*/ $sql = "INSERTAR EN `". BEZ_DBPREFIX ."reg ` VALORES("", "" .escape_str($_POST["email"]) ."", "". $pass ."", "". $salt ."", "". md5($salt) . "", 0)"; $ res = mysqlQuery($sql); //Enviar correo electrónico de activación $url = BEZ_HOST ."less/reg/?mode=reg&key=". md5($salt); $title = "(! LANG:Registro en http:/ /sitio web"; $message = "Для активации Вашего акаунта пройдите по ссылке ". $url .""; sendMessageMail($_POST["email"], BEZ_MAIL_AUTOR, $title, $message); //Сбрасываем параметры header("Location:". BEZ_HOST ."less/reg/?mode=reg&status=ok"); exit; } } } } ?>!}
REG_FORM.ARCHIVO HTML
Registro de usuario de PHP MySQL con correo electrónico de activación
Campos con un icono * requerido
Ya que nuestro registro de usuario está listo, es hora de escribir la autorización. Crearemos un formulario para la autorización del usuario, luego escribiremos un manejador de formulario de autorización y, finalmente, haremos un script mostrar.php que nos indicará si estamos autorizados en el sistema o no.
ARCHIVO AUT.PHP
!defined("BEZ_KEY")) { header("HTTP/1.1 404 Not Found"); exit(file_get_contents("./../../404.html")); } //Если нажата кнопка то обрабатываем данные if(isset($_POST["submit"])) { if(empty($_POST["email"])) $err = "Не введен Логин"; if(empty($_POST["pass"])) $err = "Не введен Пароль"; //Проверяем наличие ошибок и выводим пользователю if(count($err) >0) echo showErrorMessage($err); else ( /*Crear una consulta de búsqueda de base de datos para autenticar al usuario*/ $sql = "SELECT * FROM `". BEZ_DBPREFIX ."reg` WHERE `login` = "". escape_str($_POST["email"]) ." " AND `status` = 1"; $res = mysqlQuery($sql); //Si el inicio de sesión coincide, verifique la contraseña if(mysql_num_rows($res) > 0) ( //Obtener datos de la tabla $fila = mysql_fetch_assoc($res ); if(md5(md5($_POST["pass"]).$row["salt"]) == $row["pass"]) ( $_SESSION["user"] = true; // Restablecer parámetros header("Ubicación:". BEZ_HOST ."less/reg/?mode=auth"); exit; ) else echo showErrorMessage("¡Contraseña incorrecta!"); ) else echo showErrorMessage("Iniciar sesión ". $_POST["correo electrónico"] ." no encontrado!"); ) ) ?>
Para aquellos que tienen la última versión de PHP, publico este script usando DOP porque extensión mysql está en desuso y se ha eliminado de la nueva versión de PHP. Descargar registro y autorizacion php mysql pdo
El archivo se actualizó el 24 de febrero de 2015.
Atención: Si está utilizando este script en un servidor local como DENWER,XAMPP, entonces no debe esperar las cartas a su buzón. Las letras están en el talón. enviar correo. EN denver puedes encontrarlos en el camino Z:\tmp\!sendmail\ Puede abrir estos archivos en cualquier cliente de correo electrónico.
Aprenderemos cómo realizar una autenticación de usuario simple en el sitio. El sitio puede tener páginas solo para usuarios autorizados y funcionarán completamente si les agregamos nuestro bloque de autenticación. Para crearlo, necesitas una base. datos mysql. Puede tener 5 columnas (mínimo) o más si desea agregar información sobre los usuarios. Llamemos a la base de datos "Userauth".
Vamos a crear los siguientes campos en él: ID para contar la cantidad de usuarios, UID para el número de identificación único del usuario, Nombre de usuario para el nombre de usuario, Correo electrónico para la dirección de correo electrónico del usuario y Contraseña para la contraseña. Puede usar el usuario y la base de datos que ya tiene para la autorización, solo, como en el caso de una nueva base de datos, cree la siguiente tabla en ella.
codigo mysql
CREATE TABLE `users` (`ID` int (11) NOT NULL AUTO_INCREMENT, `UID` int (11) NOT NULL, `Username` text NOT NULL, `Email` text NOT NULL, `Password` text NOT NULL, PRIMARY KEY (`ID`)) MOTOR=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
Ahora vamos a crear el archivo "sql.php". Es responsable de conectarse a la base de datos. Este código primero crea variables para el servidor y el usuario cuando se conecta al servidor. En segundo lugar, seleccionará la base de datos, en este caso "USERAUTH". Este archivo debe estar incluido en "log.php" y "reg.php" para acceder a la base de datos.
codigo PHP
//Tu nombre de usuario de MySQL$pase = "redere"; //contraseña $conn = mysql_connect ($servidor, $usuario, $contraseña); // conexión al servidor$db = mysql_select_db("userauth", $conn); //seleccionar base de datos si (!$db) ( //si no se puede seleccionar la base de datos echo "Lo siento, error:(/>"; //Mostrar mensaje de error salida(); //Permite que se ejecuten otros scripts PHP } ?>
La siguiente es la página de inicio de sesión, llamémosla "login.php". En primer lugar, comprueba los datos introducidos en busca de errores. La página tiene campos para nombre de usuario, contraseña, un botón de envío y un enlace de registro. Cuando el usuario hace clic en el botón "Iniciar sesión", el código del archivo "log.php" procesará el formulario y luego se iniciará la sesión.
codigo PHP
0) { //si hay errores de sesion$err = "
" . $mensaje . " |
Luego escribimos un script para iniciar sesión. Llamémoslo "log.php". Tiene una función para limpiar las entradas de inyección de SQL que pueden estropear su secuencia de comandos. En segundo lugar, recibe los datos del formulario y los valida para su validez. Si los datos de entrada son correctos, el script envía al usuario a la página de usuarios autorizados; si no, corrige los errores y envía al usuario a la página de inicio de sesión.
codigo PHP
//iniciar sesion para grabar función Fix($str) ( //borrar campos $str = trim($str); if (get_magic_quotes_gpc()) ($str = stripslashes ($str); ) //matriz para almacenar errores$errflag = falso; //indicador de error $nombre de usuario = Fix($_POST["nombre de usuario"]); //Nombre de usuario$contraseña = Fix($_POST["contraseña"]);//contraseña ) //comprobar contraseña if ($contraseña == "") ( $errmsg = "Contraseña faltante"; //error $errflag = true; //levantar bandera en caso de error) //si aparece el indicador de error, se redirige de nuevo al formulario de registro // registra errores sesión_escribir_cerrar(); //cerrando la sesion // redirigir salida(); ) //solicitud a la base de datos$qry = "SELECT * FROM `users` WHERE `Username` = "$username" AND `Password` = "" . md5 ($password) . """; $resultado = mysql_query($qry); // verifique si la solicitud fue exitosa (si hay datos en ella) if (mysql_num_rows ($resultado) == 1) ( while ($fila = mysql_fetch_assoc ($resultado)) ( $_SESSION["UID"] = $fila["UID"]; //obtener el UID de la base de datos y ponerlo en la sesión$_SESSION["USERNAME"] = $usuario; //establece si el nombre de usuario coincide con el de la sesión sesión_escribir_cerrar(); //cerrando la sesion encabezado ("ubicación: miembro.php"); // redirigir) ) else ( $_SESSION["ERRMSG"] = "Usuario o contraseña no válidos"; //error session_write_close(); //cerrando la sesion encabezado ("ubicación: inicio de sesión.php"); // redirigir salida(); ) ?>
Hagamos una página de registro, llamémosla "registrar.php". Es similar a la página de inicio de sesión, solo que tiene algunos campos más y, en lugar de un enlace de registro, un enlace a login.php en caso de que el usuario ya tenga una cuenta.
codigo PHP
0) { //si hay errores de sesion$err = "
" . $mensaje . " |
Ahora hagamos un script de registro en el archivo "reg.php". Incluirá "sql.php" para conectarse a la base de datos. Se utiliza la misma función que en el script de inicio de sesión para borrar el campo de entrada. Se establecen variables para posibles errores. Lo siguiente es una función para crear un identificador único que nunca se ha proporcionado antes. Luego, los datos se recuperan del formulario de registro y se validan. Comprueba que la dirección de correo electrónico esté en el formato correcto y que la contraseña se haya vuelto a introducir correctamente. Luego, el script verifica si hay un usuario con el mismo nombre en la base de datos y, de ser así, informa un error. Y finalmente, el código agrega al usuario a la base de datos.
codigo PHP
//iniciar sesion para grabar función Fix($str) ( //borrar campos $str = @trim($str); if (get_magic_quotes_gpc()) ($str = stripslashes ($str); ) devolver mysql_real_escape_string($cadena); ) $mensajeerror = array(); //matriz para almacenar errores$errflag = falso; //indicador de error $UID = "12323543534523453451465685454";//ID único $nombre de usuario = Fix($_POST["username"]); //Nombre de usuario$correo electrónico = $_POST["correo electrónico"]; //Correo electrónico $contraseña = Fix($_POST["password"]);//contraseña $rpassword = Fix($_POST["rpassword"]);//contraseña repetida //comprobar nombre de usuario if ($usuario == "") ($errmsg = "Falta el nombre de usuario"; //error $errflag = true; // levantar la bandera en caso de error) //compruebe el correo electrónico si(!eregi("^[_a-z0-9-]+(\.[_a-z0-9-]+)*@+(\.+)*(\.(2,3 ))$", $email)) ( //debe seguir el formato: [correo electrónico protegido]$errmsg = "Correo electrónico inválido"; //error $errflag = true; // levantar la bandera en caso de error } //comprobar contraseña if ($contraseña == "") ($errmsg = "Falta la contraseña"; //error $errflag = true; // levantar la bandera en caso de error } //comprobar repetición de contraseña if ($rpassword == "") ($errmsg = "Falta la contraseña repetida";//error $errflag = true; // levantar la bandera en caso de error } // comprobar si la contraseña es válida if (strcmp($contraseña, $rcontraseña) != 0) ( $errmsg = "Las contraseñas no coinciden";//error $errflag = true; // levantar la bandera en caso de error } //comprueba si el nombre de usuario es libre if ($usuario!= "") ( $qry = "SELECT * FROM `users` WHERE `Username` = "$username""; // consulta MySQL $resultado = mysql_query ($qry); if ($resultado) ( if (mysql_num_rows ($resultado) > 0) ( //si el nombre ya está en uso$errmsg = "Nombre de usuario ya en uso"; //mensaje de error$errflag = verdadero; // levantar la bandera en caso de error) mysql_free_result($resultado); ) ) //si los datos no están validados, redirige de nuevo al formulario de registro if ($errflag) ( $_SESSION["ERRMSG"] = $errmsg; //mensaje de error sesión_escribir_cerrar(); //cerrando la sesion encabezado ("ubicación: registro.php"); // redirigir salida(); ) //añadiendo datos a la base de datos$qry = "INSERTAR EN `userauth`.`users`(`UID`, `Nombre de usuario`, `Correo electrónico`, `Contraseña`) VALUES("$UID","$nombre de usuario","$correo electrónico","" . md5 ($contraseña) . """); $resultado = mysql_query($qry); //verificar si la solicitud de agregar fue exitosa if ($resultado) ( echo "Gracias por registrarse, " .$nombre de usuario . ". Inicie sesión aquí"; salir (); ) else ( die ("Error, vuelva a consultar más tarde"); ) ?>
También debe crear un script para cerrar la sesión del usuario en el sistema. Termina la sesión para el usuario con la identificación y el nombre únicos dados, y luego redirige al usuario a la página de inicio de sesión.
codigo PHP
Finalmente, el script "auth.php" se puede usar para hacer que las páginas sean accesibles solo para usuarios autorizados. Comprueba los datos de inicio de sesión y, si son correctos, permite al usuario ver las páginas y, si no, solicita iniciar sesión. Además, si alguien intenta piratear el sitio creando una de las sesiones, se cancelará, como en el caso general.
codigo PHP
Una de las condiciones del código anterior es el tema de la pregunta en .
El siguiente código debe insertarse en la página para usuarios autorizados, se llama, por ejemplo, "member.php", y puedes llamarlo como quieras.
codigo PHP
Está autorizado a acceder a esta página. Salir ( )
¡La autenticación de usuario está lista!
Restringir el acceso a alguna zona del sitio suele parecer
monótonamente: cada usuario recibe un nombre de usuario y una contraseña o él mismo
los selecciona, y debe ingresarlos para ingresar a la parte segura del sitio. Desde un punto de vista técnico, la verificación de contraseñas utiliza
diferentes métodos. Se puede utilizar un formulario HTML para introducir un nombre de usuario y una contraseña.
En este caso, la contraseña se envía al servidor en texto claro en la solicitud POST.
Esto es inaceptable si el usuario está en LAN donde sea posible
utilizando un rastreador. Para solucionar este problema se ha desarrollado un método
autenticación hash, en la que no se transmite la contraseña, pero
se pasa una cadena hash, dependiendo de la contraseña, algunos de una sola vez
parámetro y, posiblemente, de cualquier otro parámetro. Este método sigue siendo
se llama desafío/respuesta porque cuando lo usa, el cliente
recibe una solicitud con un parámetro único y envía una respuesta que contiene el hash. En el nivel de protocolo HTTP 1.1, la autenticación es posible utilizando el método
Basic, que no es mejor que usar un formulario HTML, y Digest, que
consideraremos en detalle.
Al usar el método Digest, como ya se mencionó, la contraseña
no se transmite y no se puede oler, pero hay otro lado
Problemas. Para verificar la contraseña, el servidor debe calcular
respuesta y compararla con la respuesta del cliente, por lo tanto, el servidor debe
almacenar la contraseña o los datos dependientes de ella, necesarios para
pasar la autenticación. De ello se sigue que una persona que ha recibido derechos
para leer cuentas (por ejemplo, usando inyección SQL), podrá obtener
acceso a páginas protegidas por el método Digest. Al usar el método
Básico es posible almacenar hashes en lugar de contraseñas, lo que no permite aumentar los derechos,
después de leer estos hashes (más adelante veremos que Digest también puede almacenar hashes,
pero tal que su conocimiento es suficiente para calcular la respuesta). Por lo tanto, nos enfrentamos a un dilema: o nuestra contraseña será husmeada,
o lo obtendrán a través de una vulnerabilidad web que definitivamente alguien encontrará,
porque el que busca siempre encuentra. ¿Existe un método de autenticación sin
ambas deficiencias: el método de autenticación de clave pública:
necesita una clave pública para la verificación y una clave secreta para la verificación,
sin embargo, HTTP 1.1 no proporciona dicho método. RFC 2069
recomienda usar SSL si la seguridad es tan importante. Solo se protege la transmisión de la contraseña y el contenido no está encriptado, por lo que
que no tiene sentido proteger los recursos con este método, desde donde el usuario
recibe información secreta. Requieren SSL. y tiene sentido
para proteger, por ejemplo, un foro o subir contenido a un sitio. Entonces, si el alojamiento no admite SSL y la autenticación debe
para estar seguros, entonces usaremos Digest. Apache tiene un módulo mod_digest. para usarlo
en la configuración (o en .htaccess) escribimos:
Resumen de tipo de autenticación
AuthUserFile<файл>
nombre de autenticación<название защищаемой области>
Requerir usuario_valido
Los archivos de usuario son creados por la utilidad
resumen Mod_digest ha sido reportado por un tiempo como vulnerable, entonces,
tal vez todavía hay algunos problemas por encontrar. Además, cuando
Traté de usarlo en casa, obtuve un error
500 Error interno del servidor. Además, si se deben agregar cuentas
automáticamente, y debería haber muchos de ellos, deberían
almacenarse no en la configuración de Apache, sino en MySQL. Solución -
usa php. PHP no tiene soporte integrado para esto.
método, por lo que tendrá que ser implementado. Para ello es necesario estudiar
este método en detalle. Observo de inmediato que el artículo presentado en este artículo
la implementación solo funciona en Apache ya que el acceso completo a los encabezados
request (función apache_request_headers) solo funciona en Apache, pero en
otros servidores pueden no estar disponibles. solo tenemos que leer
Encabezado de autorización.
Descripción del método
La descripción completa del método se puede encontrar en RFC 2069, y si
en resumen, el método funciona así. Cuando el servidor recibe una solicitud relacionada con un área protegida,
arroja un error de Autorización requerida 401 y un encabezado de solicitud
autenticación como esta:
WWW-Authenticate: Digest realm="área segura", nonce="123456123456"
realm es el nombre del área protegida y el nonce es la única vez
significado. Hay más parámetros opcionales que discutimos
nosotros no. El cliente repite la solicitud con un encabezado como este:
Autorización: Digest realm="área segura", nombre de usuario="123", uri="/index.php", nonce="123456123456", respuesta="1234567890abcdef1234567890abcdef"
El parámetro uri debe coincidir con el URI en la solicitud y la respuesta es
la respuesta, que se calcula así:
respuesta = H(H(A1) + ":" + nonce + ":" + H(A2))
H - función hash, por defecto MD5
A1 = inicio de sesión + ":" + reino + ":" + contraseña
A2 = método de solicitud + ":" + URI
el método de solicitud es GET, POST, etc.
Como puede ver, A1 no depende ni de la consulta ni de la única vez
valores, por lo que el servidor no puede almacenar la contraseña, pero
H(A1). Así se implementa en mod_digest en Apache.
Sin embargo, los mismos datos son suficientes para el cliente. El atacante, habiendo recibido
este hash, puede calcular la respuesta con las fórmulas anteriores y
generar una solicitud HTTP, por ejemplo, usando el programa
AccessDriver y su herramienta HTTP
depurador Este proceso se mostrará con más detalle a continuación. El servidor debe verificar si el valor es un nonce
el que fue emitido previamente al cliente y si está desactualizado.
Si la respuesta coincide con el parámetro nonce, pero el valor de este parámetro
no relevante, la respuesta descrita anteriormente con el código 401 se emite con el único
la diferencia es que el encabezado WWW-Authenticate se agrega con el parámetro
stale=true que indica que el acceso está denegado solo por este motivo,
y debe volver a intentarlo sin solicitar al usuario una nueva contraseña. Esto, en mi humilde opinión, es un inconveniente, porque si surge tal situación
al solicitar un POST o PUT con un gran bloque de datos, el cliente tendrá que
transferir todos los datos dos veces. Para evitar esto, la norma establece
el encabezado de información de autenticación, en el que el servidor puede, al responder a
una solicitud exitosa informa al cliente del próximo nonce.
La sintaxis es la misma que WWW-Authenticate, excepto por el nonce
se reemplaza por nextnonce. Sin embargo, a juzgar por los resultados de mi
experimentos, Opera ignora este encabezado. Otra solución: según
RFC 2068 (HTTP/1.1), el servidor PUEDE responder antes de que se complete la solicitud,
para que el cliente interrumpa la transferencia de datos innecesaria, pero en Apache+PHP esto
no está implementado, porque el script comienza a ejecutarse solo después de
cómo Apache recibirá y analizará completamente la solicitud.
Almacenamiento de datos entre solicitudes
Hay un punto sutil en la implementación de PHP del método de desafío/respuesta.
El parámetro único se forma y se emite al cliente en una respuesta, y
comprobado ya en otra sesión del script.
Es decir, se debe guardar de una llamada de script a otra, y para ello hay que
utilizar archivos o base de datos. Mi ejemplo usa archivos llamados,
valores únicos correspondientes, y los propios archivos contienen
Las direcciones IP de los clientes a los que se emiten. La colección no está implementada en el ejemplo.
basura: debe eliminar periódicamente los archivos antiguos.
análisis de código
Este script solo verifica la contraseña y funciona independientemente de
acceso. Dependiendo del éxito de la verificación, se emiten respuestas simples.
$reino = "área segura"; // nombre del área protegida
$pase = "pase"; // Contraseña
$prefijoarchivo = "./"; // Ruta para archivos de etiquetas que indican la validez del nonce
/*
Construyamos un parámetro de una sola vez como se recomienda en RFC2069, aunque es posible de otra manera. El parámetro, según la recomendación, debe depender de la dirección del cliente, la hora actual y la cadena secreta. */
$nonce = md5($_SERVER["REMOTE_ADDR"] . ":" . time() . ":MyCooolPrivateKey");
// Obtener encabezados
$encabezados = apache_request_headers();
// Indicador que estableceremos en VERDADERO en una validación exitosa
$auth_success = FALSO;
$obsoleto = "";
// Si no hay un encabezado de Autorización, entonces no hay nada que verificar
if (isset($headers["Autorización"]))
{
$autorización = $cabeceras["Autorización"];
/* Analice el título usando una expresión regular. El título contiene la palabra "Digest" y una lista
parámetros de la forma param="valor" o param=valor separados por comas. Esta expresión regular coincide con uno de esos parámetros. */
preg_match_all("/(,|\s|^)(\w+)=("([^"]*)"|([\w\d]*))(,|$)/",
$autorización, $coincidencias, PREG_SET_ORDER);
/* Ahora, para facilitar el procesamiento posterior, formaremos una matriz, donde las claves son los nombres de los parámetros y los valores de los elementos de la matriz son
valores paramétricos. */
$auth_params = array();
para ($i = 0; $i< count($matches); $i++)
{
$coincidencia = $coincidencias[$i];
/* El nombre siempre está en el segundo grupo de corchetes, dependiendo de si está entre comillas o no, puede
estar en el 4to o 5to grupo. Para grupos de corchetes cogidos
a una rama no realizada, una cadena vacía en la matriz,
así que solo puedes agregar los valores.*/
$auth_params[$coincidencia] = $coincidencia . $coincidencia;
}
/* Calcule la respuesta que coincida
el inicio de sesión ingresado por el usuario, nuestra contraseña y el parámetro de una sola vez pasado por el usuario.
*/
$a1 = $auth_params["nombre de usuario"] . ":" . $auth_params["reinos"] . ":" . $pasar;
$a2 = $_SERVIDOR["REQUEST_METHOD"] . ":" . $_SERVIDOR["SOLICITUD_URI"];
$resp = md5(md5($a1) . ":" . $auth_params["nonce"] . ":" . md5($a2));
// Comprobamos la respuesta.
si ($resp == $auth_params["respuesta"])
{
//
Comprobación de la relevancia de un parámetro único
$fn = $prefijoarchivo. $auth_params["nonce"];
si (@file_get_contents($fn) == $_SERVER["REMOTE_ADDR"])
{
desvincular ($fn); //Esta opción ya no es relevante.
$auth_success = VERDADERO; //Autenticación aprobada
) demás
{
//
El parámetro único es irrelevante
$obsoleto = ", obsoleto=verdadero";
}
}
}
si ($auth_success)
{
imprimir("
print("Autenticado con exito\n");
var_dump($auth_params);
imprimir("");
) demás
{
file_put_contents($fileprefix . $nonce, $_SERVER["REMOTE_ADDR"]);
$proto = $_SERVIDOR["PROTOCOLO_SERVIDOR"];
Encabezado("$proto 401 No Autorizado");
Header("WWW-Authenticate: Digest realm=\"$reino\", nonce=\"$nonce\"$stale");
imprimir("
");
print("Debe autenticarse con el método Digest");
imprimir("
");
}
Aprobación de autenticación implícita con H(A1) conocido
Mostraré con un ejemplo cómo pasar la verificación si se desconoce la contraseña,
pero se conoce H(A1). Para hacer esto, como ya se mencionó, necesita
Controlador de acceso. Haré cálculos hash llamando desde la línea de comando
CLI de PHP. Que la página protegida se ubique en
http://mrblack.local/auth1.php y el hash H(A1) es "a8fb5b2d780a7bf0782207a51a013f04".
Abra AccessDriver->Tools->HTTP Debugger e ingrese la dirección
"http://mrblack.local/auth1.php". Haga clic en "Conectar". Obtenemos:
Encabezado HTTP = HTTP/1.1 401 Se requiere autorización
Encabezado HTTP = Fecha: lunes, 04 de julio de 2005 08:09:17 GMT
Encabezado HTTP = Servidor: Apache/1.3.31 (Win32) PHP/5.0.2
Encabezado HTTP = X-Powered-By: PHP/5.0.2
Encabezado HTTP = WWW-Authenticate: Digest realm="área segura", nonce="5925bea78552224abda11bfe318a8a03"
Encabezado HTTP = Conexión: cerrar
Encabezado HTTP = Tipo de contenido: texto/html
Abra la consola, vaya a la carpeta con PHP e ingrese el siguiente comando:
php -r "imprimir md5("a8fb5b2d780a7bf0782207a51a013f04:
: ".md5("OBTENER:http://mrblack.local/auth1.php"));"
Obtenemos la respuesta Digest deseada: c6d0af0db239d75c
3f59640a4896d096
Ahora en AccessDriver, marque la casilla de verificación "Header Data", cópielo en el que aparece
los encabezados de campo que se enviaron en la solicitud anterior y anexarlos
Autorización. Esto es lo que sucede:
OBTENGA http://mrblack.local/auth1.php HTTP/1.1
Aceptar: imagen/gif, imagen/x-xbitmap, imagen/jpeg, imagen/pjpeg, aplicación/x-shockwave-flash, */*
Aceptar-Idioma: en-us,en;q=0.5
Agente de usuario: compatible con Mozilla
Anfitrión: mrblack.local
Pragma: sin caché
Autorización: Digest nombre de usuario="mrblack", reino="área segura", nonce="5925bea78552224ab
da11bfe318a8a03", uri="http://mrblack.local/auth1.php", respuesta="c6d0af0db239d75c3f59
640a4896d096"
Haga clic en "Conectar". Obtenemos el resultado:
Es posible utilizar la función encabezamiento() para enviar un mensaje "Autenticacion requerida" navegador, obligándolo a mostrar una ventana para ingresar un nombre de usuario y contraseña. Una vez que el usuario haya ingresado el nombre de usuario y la contraseña, se llamará nuevamente al enlace que contiene el script PHP con las variables predefinidas PHP_AUTH_USER, PHP_AUTH_PW y AUTH_TYPE configuradas en nombre de usuario, contraseña y tipo de autenticación respectivamente. Estas variables predefinidas se almacenan en las matrices $_SERVER y $HTTP_SERVER_VARS. Se admiten ambos tipos: "Básico" y "Digest" (a partir de PHP 5.1.0). Vea la función para más detalles. encabezamiento().
Un ejemplo de un fragmento de secuencia de comandos que obliga al cliente a iniciar sesión para ver la página:
Beispiel #6 Ejemplo básico de autenticación HTTP
if (!isset($_SERVER [ "PHP_AUTH_USER" ])) (
encabezamiento( "WWW-Authenticate: Reino básico="Mi reino"");
eco "Texto a enviar si
si el usuario hizo clic en el botón Cancelar";
salida;
) demás (
eco"
Hola ($_SERVER [ "PHP_AUTH_USER" ]) .
" ;eco "
Has introducido una contraseña
( $_SERVIDOR [ "PHP_AUTH_PW" ]) ." ;}
?>
Beispiel #7 Ejemplo de autenticación HTTP Digest
Este es un ejemplo de implementación de un simple script de autenticación HTTP Digest. Ver » RFC 2617 para más detalles.
$reino = "Área restringida" ;
//usuario => contraseña
$usuarios = array("admin" => "micontraseña", "invitado" => "invitado");
si (vacío($_SERVIDOR [ "PHP_AUTH_DIGEST" ])) (
encabezado ("HTTP/1.1 401 no autorizado");
encabezamiento( "WWW-Authenticate: Digest realm="". $reinos.
"",qop="autorización",nonce="" . uniqid(). "",opaco="" . md5 ($reino). """);
Morir( "El texto enviado si el usuario hizo clic en Cancelar");
}
// analizar la variable PHP_AUTH_DIGEST
si (!($datos = http_digest_parse ($_SERVER [ "PHP_AUTH_DIGEST" ])) ||
!isset($usuarios [ $datos [ "nombre de usuario" ]]))
morir( "¡Información incorrecta!");
// generar la respuesta correcta
$A1 = md5 ($datos [ "nombre de usuario" ] . ":" . $reino . ":" . $usuarios [ $datos [ "nombre de usuario" ]]);
$A2 = md5($_SERVER [ "REQUEST_METHOD" ]. ":" . $datos [ "uri" ]);
$respuesta_válida = md5 ($A1 . ":" . $datos [ "nonce" ]. ":" . $datos [ "nc" ]. ":" . $datos [ "cnonce" ]. ":" . $datos [ "qop" ]. ":". $A2 );
if ($datos [ "respuesta" ] != $valid_response )
morir( "¡Información incorrecta!");
// ok, el nombre de usuario y la contraseña son correctos
echo "Usted ha iniciado sesión como: ". $datos["nombre de usuario"];
// función de análisis del encabezado de autenticación http
función http_digest_parse($txt)
{
// proteger contra la falta de datos
$piezas_necesarias = matriz("nonce" => 1 , "nc" => 1 , "cnonce" => 1 , "qop" => 1 , "nombre de usuario" => 1 , "uri" => 1 , "respuesta" => 1);
$datos = matriz();
$keys = implode ("|" , array_keys ($needed_parts ));
preg_match_all ("@(" . $claves . ")=(?:([\""])([^\2]+?)\2|([^\s,]+))@", $txt , $coincidencias , PREG_SET_ORDER );
Foreach ($coincide con $m) (
$datos [ $m [ 1 ]] = $m [ 3 ] ? $m [ 3 ] : $m [ 4 ];
unset($necesita_partes [ $m [ 1 ]]);
}
¿Devolver $needed_parts? falso: $datos;
}
?>
Comentario: Nota de compatibilidad
Tenga especial cuidado al especificar encabezados HTTP. Para garantizar la máxima compatibilidad con el mayor número de clientes diferentes, la palabra "Básico" debe escribirse con "B" mayúscula, la región (reino) debe estar entre comillas dobles (¡no simples!), y debe preceder exactamente un espacio a la código 401 En el título HTTP/1.0 401. Los parámetros de autenticación deben estar separados por comas, como se muestra en el ejemplo de autenticación Digest anterior.
En lugar de simplemente mostrar las variables PHP_AUTH_USER y PHP_AUTH_PW en la pantalla, es posible que deba verificar si son correctas. Para ello, utilice una consulta de base de datos o busque un usuario en un archivo dbm.
Puede observar las características del navegador Internet Explorer. Es muy exigente con el parámetro de los encabezados transmitidos. Truco de encabezado WWW-Autenticar antes de enviar el estado HTTP/1.0 401 hasta ahora le funciona.
A partir de PHP 4.3.0, para evitar que alguien escriba un script que revele la contraseña de una página que usa autenticación externa, las variables PHP_AUTH no se configuran si esa página usa autenticación externa y se configura el modo seguro. Independientemente, la variable REMOTE_USER se puede usar para autenticar a un usuario autenticado externamente. Por lo tanto, siempre puede usar la variable $_SERVER["REMOTE_USER"] .
Comentario: Nota de configuración
PHP usa indicación de directiva Tipo de autenticación para indicar si se utiliza autenticación externa o no.
Cabe señalar que todo lo anterior no impide que las contraseñas de las páginas que requieran autorización sean sustraídas por cualquier persona que controle páginas sin autorización ubicadas en el mismo servidor.
Tanto Netscape Navigator como Internet Explorer borran la memoria caché de autenticación de la ventana actual para el dominio dado cuando se reciben del servidor. Esto se puede usar para obligar al usuario a cerrar sesión y volver a mostrar el cuadro de diálogo de nombre de usuario y contraseña. Algunos desarrolladores usan esto para limitar el tiempo de inicio de sesión o para proporcionar un botón de cierre de sesión.
Beispiel #8 Ejemplo de autenticación HTTP que fuerza un nuevo par de inicio de sesión/contraseña
función autenticar()(
encabezamiento( "WWW-Authenticate: dominio básico="Sistema de autenticación de prueba"");
encabezado ("HTTP/1.0 401 no autorizado");
eco "Debe ingresar un nombre de usuario y una contraseña válidos para acceder al recurso \n";
salida;
}
si (!isset($_SERVER [ "PHP_AUTH_USER" ]) || Bienvenido: "
($_POST [ "Visto antes" ] == 1 && $_POST [ "OldAuth" ] == $_SERVER [ "PHP_AUTH_USER" ])) (
autenticar();
) demás (
eco "
"
;
eco "Inicio de sesión anterior: ". htmlspecialchars($_REQUEST["OldAuth"]);
eco ";
eco "\norte";
eco ". htmlspecialchars ($_SERVER [ "PHP_AUTH_USER" ]) . "\" />\n" ;
eco "\norte";
eco "
}
?>
Este comportamiento no está regulado por las normas. HTTP básico-autenticación, por lo tanto, no debe depender de ella. prueba del navegador Lince mostró que Lince no borra el caché de autorización cuando recibe un estado 401 del servidor, y al hacer clic en "Atrás" y luego en "Adelante" en secuencia, es posible abrir dicha página, siempre que los atributos de autorización requeridos no hayan cambiado. Sin embargo, el usuario puede presionar la tecla "_" para borrar la caché de autenticación.
También tenga en cuenta que antes de PHP 4.3.3, la autenticación HTTP no funcionaba en servidores que ejecutaban Microsoft IIS si PHP estaba instalado como un módulo CGI, debido a algunas restricciones de IIS. Para que funcione correctamente en PHP 4.3.3+, debe editar la configuración de IIS llamada " Seguridad del directorio". Haga clic en la inscripción " Editar" y establecer la opción " Acceso anónimo", todos los demás campos deben dejarse sin marcar.
Otra limitación si está utilizando IIS a través de ISAPI y PHP 4: Variables PHP_AUTH_* no están definidos, pero al mismo tiempo la variable está disponible AUTORIZACIÓN_HTTP. Ejemplo de código que podrías usar: list($usuario, $pw) = explotar(":", base64_decode(substr($_SERVER["HTTP_AUTHORIZATION"], 6)));
Comentario: Nota sobre IIS:
Para que la autenticación HTTP funcione correctamente en IIS, la opción cgi.rfc2616_headers en la configuración de PHP debe establecerse en 0 (valor por defecto).
Comentario:
En caso de que se use el modo seguro, el UID del script actual se agregará a reinos-parte del encabezado WWW-Autenticar.
Es posible utilizar la función encabezamiento() para enviar un mensaje "Autenticacion requerida" navegador, obligándolo a mostrar una ventana para ingresar un nombre de usuario y contraseña. Una vez que el usuario haya ingresado el nombre de usuario y la contraseña, se llamará nuevamente al enlace que contiene el script PHP con las variables predefinidas PHP_AUTH_USER, PHP_AUTH_PW y AUTH_TYPE configuradas en nombre de usuario, contraseña y tipo de autenticación respectivamente. Estas variables predefinidas se almacenan en las matrices $_SERVER y $HTTP_SERVER_VARS. Se admiten ambos tipos: "Básico" y "Digest" (a partir de PHP 5.1.0). Vea la función para más detalles. encabezamiento().
Un ejemplo de un fragmento de secuencia de comandos que obliga al cliente a iniciar sesión para ver la página:
Beispiel #1 Ejemplo básico de autenticación HTTP
if (!isset($_SERVER [ "PHP_AUTH_USER" ])) (
encabezamiento( "WWW-Authenticate: Reino básico="Mi reino"");
eco "Texto a enviar si
si el usuario hizo clic en el botón Cancelar";
salida;
) demás (
eco"
Hola ($_SERVER [ "PHP_AUTH_USER" ]) .
" ;eco "
Has introducido una contraseña
( $_SERVIDOR [ "PHP_AUTH_PW" ]) ." ;}
?>
Beispiel #2 Ejemplo de autenticación HTTP Digest
Este es un ejemplo de implementación de un simple script de autenticación HTTP Digest. Ver » RFC 2617 para más detalles.
$reino = "Área restringida" ;
//usuario => contraseña
$usuarios = array("admin" => "micontraseña", "invitado" => "invitado");
si (vacío($_SERVIDOR [ "PHP_AUTH_DIGEST" ])) (
encabezado ("HTTP/1.1 401 no autorizado");
encabezamiento( "WWW-Authenticate: Digest realm="". $reinos.
"",qop="autorización",nonce="" . uniqid(). "",opaco="" . md5 ($reino). """);
Morir( "El texto que se enviará cuando el usuario haga clic en el botón Cancelar");
}
// analizar la variable PHP_AUTH_DIGEST
si (!($datos = http_digest_parse ($_SERVER [ "PHP_AUTH_DIGEST" ])) ||
!isset($usuarios [ $datos [ "nombre de usuario" ]]))
morir( "¡Información incorrecta!");
// generar la respuesta correcta
$A1 = md5 ($datos [ "nombre de usuario" ] . ":" . $reino . ":" . $usuarios [ $datos [ "nombre de usuario" ]]);
$A2 = md5($_SERVER [ "REQUEST_METHOD" ]. ":" . $datos [ "uri" ]);
$respuesta_válida = md5 ($A1 . ":" . $datos [ "nonce" ]. ":" . $datos [ "nc" ]. ":" . $datos [ "cnonce" ]. ":" . $datos [ "qop" ]. ":". $A2 );
if ($datos [ "respuesta" ] != $valid_response )
morir( "¡Información incorrecta!");
// ok, el nombre de usuario y la contraseña son correctos
echo "Usted ha iniciado sesión como: ". $datos["nombre de usuario"];
// función de análisis del encabezado de autenticación http
función http_digest_parse($txt)
{
// proteger contra la falta de datos
$piezas_necesarias = matriz("nonce" => 1 , "nc" => 1 , "cnonce" => 1 , "qop" => 1 , "nombre de usuario" => 1 , "uri" => 1 , "respuesta" => 1);
$datos = matriz();
$keys = implode ("|" , array_keys ($needed_parts ));
preg_match_all ("@(" . $claves . ")=(?:([\""])([^\2]+?)\2|([^\s,]+))@", $txt , $coincidencias , PREG_SET_ORDER );
Foreach ($coincide con $m) (
$datos [ $m [ 1 ]] = $m [ 3 ] ? $m [ 3 ] : $m [ 4 ];
unset($necesita_partes [ $m [ 1 ]]);
}
¿Devolver $needed_parts? falso: $datos;
}
?>
Comentario: Nota de compatibilidad
Tenga especial cuidado al especificar encabezados HTTP. Para garantizar la máxima compatibilidad con el mayor número de clientes diferentes, la palabra "Básico" debe escribirse con "B" mayúscula, la región (reino) debe estar entre comillas dobles (¡no simples!), y debe preceder exactamente un espacio a la código 401 En el título HTTP/1.0 401. Los parámetros de autenticación deben estar separados por comas, como se muestra en el ejemplo de autenticación Digest anterior.
En lugar de simplemente mostrar las variables PHP_AUTH_USER y PHP_AUTH_PW en la pantalla, es posible que deba verificar si son correctas. Para ello, utilice una consulta de base de datos o busque un usuario en un archivo dbm.
Puede observar las características del navegador Internet Explorer. Es muy exigente con el parámetro de los encabezados transmitidos. Truco de encabezado WWW-Autenticar antes de enviar el estado HTTP/1.0 401 hasta ahora le funciona.
Para evitar que alguien escriba un script que revele la contraseña de una página que usa autenticación externa, las variables PHP_AUTH no se configuran si esa página usa autenticación externa y el modo seguro está configurado. Independientemente, la variable REMOTE_USER se puede usar para autenticar a un usuario autenticado externamente. Por lo tanto, siempre puede usar la variable $_SERVER["REMOTE_USER"] .
Comentario: Nota de configuración
PHP usa indicación de directiva Tipo de autenticación para indicar si se utiliza autenticación externa o no.
Cabe señalar que todo lo anterior no impide que las contraseñas de las páginas que requieran autorización sean sustraídas por cualquier persona que controle páginas sin autorización ubicadas en el mismo servidor.
Tanto Netscape Navigator como Internet Explorer borran la memoria caché de autenticación de la ventana actual para el dominio dado cuando recibe un estado 401 del servidor. Esto se puede usar para obligar al usuario a cerrar la sesión y volver a mostrar el cuadro de diálogo de nombre de usuario y contraseña. Algunos desarrolladores usan esto para limitar el tiempo de inicio de sesión o para proporcionar un botón de cierre de sesión.
Beispiel #3 Ejemplo de autenticación HTTP que fuerza un nuevo par de inicio de sesión/contraseña
función autenticar()(
encabezamiento( "WWW-Authenticate: dominio básico="Sistema de autenticación de prueba"");
encabezado ("HTTP/1.0 401 no autorizado");
eco "Debe ingresar un nombre de usuario y una contraseña válidos para acceder al recurso \n";
salida;
}
si (!isset($_SERVER [ "PHP_AUTH_USER" ]) || Bienvenido: "
($_POST [ "Visto antes" ] == 1 && $_POST [ "OldAuth" ] == $_SERVER [ "PHP_AUTH_USER" ])) (
autenticar();
) demás (
eco "
"
;
eco "Inicio de sesión anterior: ". htmlspecialchars($_REQUEST["OldAuth"]);
eco ";
eco "\norte";
eco ". htmlspecialchars ($_SERVER [ "PHP_AUTH_USER" ]) . "\" />\n" ;
eco "\norte";
eco "
}
?>
Este comportamiento no está regulado por las normas. HTTP básico-autenticación, por lo tanto, no debe depender de ella. prueba del navegador Lince mostró que Lince no borra el caché de autorización cuando recibe un estado 401 del servidor, y al hacer clic en "Atrás" y luego en "Adelante" en secuencia, es posible abrir dicha página, siempre que los atributos de autorización requeridos no hayan cambiado. Sin embargo, el usuario puede presionar la tecla "_" para borrar la caché de autenticación.
Para que la autenticación HTTP funcione correctamente en un servidor IIS con una versión CGI de PHP, debe editar la configuración de IIS llamada " Seguridad del directorio". Haga clic en la inscripción " Editar" y establecer la opción " Acceso anónimo", todos los demás campos deben dejarse sin marcar.
Comentario: Nota sobre IIS:
Para que la autenticación HTTP funcione correctamente en IIS, la opción cgi.rfc2616_headers en la configuración de PHP debe establecerse en 0 (valor por defecto).
Comentario:
En caso de que se use el modo seguro, el UID del script actual se agregará a reinos-parte del encabezado WWW-Autenticar.