Usuarios y permisos en MySQL
MySQL tiene su propio sistema de usuarios, completamente independiente del sistema operativo. Cada conexión a la base de datos debe autenticarse con un usuario MySQL que tiene asociados unos permisos concretos: qué bases de datos puede ver, qué operaciones puede ejecutar, y desde qué máquinas puede conectarse.
¿Por qué no usar root en tus aplicaciones?
Durante la instalación y el aprendizaje es cómodo conectarse como root. Pero en una aplicación web real, conectar PHP (o cualquier otro lenguaje) a la base de datos usando root es un error grave de seguridad.
Imagina que tu aplicación tiene una vulnerabilidad de inyección SQL. Si se ejecuta como root, el atacante puede hacer cualquier cosa: borrar todas las bases de datos del servidor, leer tablas de otras aplicaciones, crear usuarios nuevos con todos los privilegios. Si en cambio se ejecuta con un usuario que solo puede hacer SELECT, INSERT, UPDATE y DELETE sobre tu base de datos, el daño posible queda drásticamente reducido.
Este principio tiene nombre: mínimo privilegio necesario. Dale a cada parte del sistema solo los permisos estrictamente necesarios para funcionar.
Nota: La regla práctica es sencilla: root es para administrar el servidor (crear bases de datos, crear usuarios, hacer backups). La aplicación web debe tener su propio usuario con permisos limitados a su base de datos.
Crear un usuario
La sintaxis básica es:
CREATE USER 'nombre_usuario'@'host' IDENTIFIED BY 'contraseña';
El host es desde dónde se permite conectar:
'localhost': solo desde la misma máquina (lo más habitual en aplicaciones web)'192.168.1.10': solo desde esa IP concreta'%': desde cualquier máquina (evitar salvo que sea imprescindible)
Ejemplo: crear un usuario para una aplicación web en el mismo servidor:
CREATE USER 'app_videclub'@'localhost' IDENTIFIED BY 'contraseña_segura_aqui';
Este usuario existe, pero todavía no puede hacer nada: no tiene permisos sobre ninguna base de datos.
Asignar permisos: GRANT
GRANT es el comando que otorga permisos a un usuario. La sintaxis es:
GRANT permisos ON base_de_datos.tabla TO 'usuario'@'host';
Para los permisos puedes especificar operaciones concretas o un conjunto:
SELECT: leer datosINSERT: insertar nuevos registrosUPDATE: modificar registros existentesDELETE: eliminar registrosCREATE,DROP,ALTER: modificar la estructura de tablasALL PRIVILEGES: todos los permisos (usar con cautela)
Ejemplo: usuario típico de aplicación web
Una aplicación de videoclub necesita leer y escribir datos, pero no necesita modificar la estructura de la base de datos (eso lo hace el desarrollador manualmente o con migraciones):
-- Permiso sobre todas las tablas de la base de datos 'videoclub'
GRANT SELECT, INSERT, UPDATE, DELETE ON videoclub.* TO 'app_videoclub'@'localhost';
El asterisco (*) después del punto significa "todas las tablas de esa base de datos".
Si quisieras ser aún más restrictivo, puedes limitar a una tabla concreta:
-- Solo puede leer la tabla 'film', nada más
GRANT SELECT ON videoclub.film TO 'usuario_informes'@'localhost';
Aplicar los cambios: FLUSH PRIVILEGES
En versiones antiguas de MySQL era necesario ejecutar esto para que los cambios de permisos surtieran efecto inmediatamente:
FLUSH PRIVILEGES;
Con MySQL moderno (5.7+), GRANT y REVOKE se aplican automáticamente. Aun así, muchos administradores lo ejecutan por costumbre después de cambios de permisos.
Ver los permisos de un usuario
SHOW GRANTS FOR 'app_videoclub'@'localhost';
Ejemplo de salida:
+-------------------------------------------------------------------------+
| Grants for app_videoclub@localhost |
+-------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'app_videoclub'@'localhost' |
| GRANT SELECT, INSERT, UPDATE, DELETE ON 'videoclub'.* TO 'app_videoclub'|
+-------------------------------------------------------------------------+
La primera línea (GRANT USAGE) significa simplemente que el usuario existe. La segunda muestra los permisos reales sobre la base de datos.
Revocar permisos: REVOKE
REVOKE es el opuesto de GRANT: quita permisos sin borrar el usuario.
-- Quitar el permiso DELETE a un usuario
REVOKE DELETE ON videoclub.* FROM 'app_videoclub'@'localhost';
Cambiar la contraseña de un usuario
ALTER USER 'app_videoclub'@'localhost' IDENTIFIED BY 'nueva_contrasena';
Eliminar un usuario
DROP USER 'app_videoclub'@'localhost';
Eliminar un usuario también elimina automáticamente todos sus permisos.
Flujo completo: crear base de datos y usuario de aplicación
Este es el proceso habitual cuando arrancas un nuevo proyecto:
-- 1. Conectarse como root
mysql -u root -p
-- 2. Crear la base de datos
CREATE DATABASE videoclub CHARACTER SET utf8mb4 COLLATE utf8mb4_spanish_ci;
-- 3. Crear el usuario de aplicación
CREATE USER 'app_videoclub'@'localhost' IDENTIFIED BY 'contraseña_segura';
-- 4. Darle permisos sobre esa base de datos
GRANT SELECT, INSERT, UPDATE, DELETE ON videoclub.* TO 'app_videoclub'@'localhost';
-- 5. Aplicar cambios
FLUSH PRIVILEGES;
-- 6. Verificar
SHOW GRANTS FOR 'app_videoclub'@'localhost';
A partir de aquí, tu aplicación PHP conecta con app_videoclub, no con root.
Ver todos los usuarios del servidor
SELECT user, host FROM mysql.user;
La tabla mysql.user es la tabla del sistema donde MySQL almacena todos los usuarios. Solo root puede consultarla.
Nota: Un usuario en MySQL siempre se identifica por la combinación usuario@host. 'app'@'localhost' y 'app'@'%' son dos usuarios completamente distintos, pueden tener contraseñas y permisos diferentes.
En la próxima lección: los distintos tipos de tablas y motores de almacenamiento de MySQL.