MySQL: ERROR 1045 Access denied for user — Cómo resetear contraseña
Cómo resolver el error 1045 'Access denied for user' en MySQL. Resetear la contraseña de root, crear usuarios y configurar permisos correctamente.
¿Por qué ocurre?
MySQL deniega el acceso porque: - La contraseña es incorrecta o ha sido cambiada - El usuario no existe en MySQL (aunque exista en el sistema operativo) - El usuario existe pero sin privilegios para el host especificado (`root@localhost` vs `root@%`) - En MySQL 8: el plugin de autenticación es `caching_sha2_password` pero el cliente usa `mysql_native_password` - La connection string tiene caracteres especiales en la contraseña sin encodear
Solución paso a paso
1. Resetear contraseña de root (método seguro)
# Detener MySQL
sudo systemctl stop mysql# Iniciar en modo sin privilegios (skip-grant-tables)
sudo mysqld_safe --skip-grant-tables --skip-networking &
# Conectar sin contraseña
mysql -u root
# Cambiar contraseña (MySQL 8)
FLUSH PRIVILEGES;
ALTER USER 'root'@'localhost' IDENTIFIED BY 'nueva_contraseña_segura';
FLUSH PRIVILEGES;
EXIT;
# Reiniciar MySQL normalmente
sudo systemctl restart mysql
2. Crear usuario con permisos (mejor práctica que usar root)
-- Conectado como root
CREATE USER 'mi_usuario'@'localhost' IDENTIFIED BY 'contraseña_segura';-- Dar acceso a una base de datos específica
GRANT ALL PRIVILEGES ON mi_base_datos.* TO 'mi_usuario'@'localhost';
-- Aplicar cambios
FLUSH PRIVILEGES;
-- Verificar permisos
SHOW GRANTS FOR 'mi_usuario'@'localhost';
3. Usuario para conexiones remotas (host %)
-- Para conectar desde cualquier IP (útil en desarrollo/Docker)
CREATE USER 'mi_usuario'@'%' IDENTIFIED BY 'contraseña';
GRANT ALL PRIVILEGES ON mi_base_datos.* TO 'mi_usuario'@'%';
FLUSH PRIVILEGES;-- Verificar que MySQL escucha en todas las interfaces
-- En /etc/mysql/mysql.conf.d/mysqld.cnf
-- bind-address = 0.0.0.0 (o comentar la línea)
4. MySQL 8: problema con el plugin de autenticación
-- Si el cliente no soporta caching_sha2_password
ALTER USER 'mi_usuario'@'localhost'
IDENTIFIED WITH mysql_native_password
BY 'contraseña';
FLUSH PRIVILEGES;
5. En Docker Compose
version: '3.8'
services:
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: root_password
MYSQL_DATABASE: mi_app
MYSQL_USER: mi_usuario
MYSQL_PASSWORD: mi_contraseña
ports:
- "3306:3306"
volumes:
- mysql_data:/var/lib/mysqlvolumes:
mysql_data:
6. Verificar conexión desde Node.js (mysql2)
import mysql from 'mysql2/promise'const pool = mysql.createPool({
host: process.env.DB_HOST || 'localhost',
user: process.env.DB_USER || 'mi_usuario',
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
waitForConnections: true,
connectionLimit: 10,
})
// Probar conexión
try {
const connection = await pool.getConnection()
console.log('MySQL conectado correctamente')
connection.release()
} catch (error) {
if (error.code === 'ER_ACCESS_DENIED_ERROR') {
console.error('Credenciales incorrectas o usuario sin permisos')
}
}
Cómo evitarlo en el futuro
- Nunca uses el usuario `root` en aplicaciones; crea usuarios específicos por base de datos - Usa variables de entorno para las credenciales, nunca las hardcodees - En producción, usa `'usuario'@'ip-especifica'` en lugar de `'usuario'@'%'` - Activa el log de auditoría de MySQL en producción para detectar intentos fallidos
¿Quieres que una IA te ayude? Genera el prompt perfecto para tu error:
Generador de Prompts