Conexión de Django a PostgreSQL: "Falló la autenticación de pares"

121
OperationalError at /admin/

FATAL:  Peer authentication failed for user "myuser"

Este es el error que recibo cuando intento acceder a mi sitio de administración de Django. Había estado usando la base de datos MySQL sin problema. Soy nuevo en PostgreSQL, pero decidí cambiar porque el host que finalmente planeo usar para este proyecto no tiene MySQL.

Por lo tanto, pensé que podría pasar por el proceso de instalación de PostgreSQL, ejecutar un syncdby estar listo.

El problema es que parece que no puedo hacer que mi aplicación se conecte a la base de datos. Puedo iniciar sesión en PostgreSQL a través de la línea de comandos o la aplicación de escritorio que descargué. Simplemente no en el guión.

Además, puedo usar manage.py shellpara acceder a la base de datos sin problemas.

¿Alguna idea?

El maestro cervecero
fuente

Respuestas:

219

Eché un vistazo a la excepción y noté que tenía que ver con la configuración de mi conexión. Volví a settings.py y vi que no tenía una configuración de Host. Agregue localhosty listo.

Mi settings.py no tenía un HOST para la base de datos MySQL, pero necesitaba agregar uno para que PostgreSQL funcione.

En mi caso, agregué localhosta la HOSTconfiguración y funcionó.

Aquí está la DATABASESsección de mi settings.py.

DATABASES = { 
    'default': { 
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': '<MYDATABASE>', 
        'USER': '<MYUSER>', 
        'PASSWORD': '<MYPASSWORD>', 
        'HOST': 'localhost', # the missing piece of the puzzle 
        'PORT': '', # optional, I don't need this since I'm using the standard port
    } 
}
El maestro cervecero
fuente
5
podría considerar mover la solución de su pregunta a su respuesta (y aceptarla). De esta manera, la pregunta seguirá siendo una pregunta y habrá respondido adecuadamente. Por cierto: ¡buen trabajo! :-)
Piotr Nowicki
3
Tuve el mismo problema con una aplicación Rails, y fue la misma solución: el host necesitaba configurarse en config/database.yml, es decir, en ese archivo necesitaba agregar la línea host: localhost(o donde sea que esté su servidor de postgres, el mío era local)
jefflunt
7
Cuando el HOST está en blanco, Django intenta conectarse a la base de datos usando sockets UNIX. Por otro lado, cuando el HOST es "localhost", se conecta a través de TCP / IP a 127.0.0.1. Probablemente, su pg_hba.confestá configurado para impedir que los usuarios normales se conecten a través de sockets UNIX, pero les permite a través de TCP / IP desde localhost.
Jim Garrison
3
La documentación ( docs.djangoproject.com/en/1.6/ref/settings/#host ) miente: "HOST [...] Una cadena vacía significa localhost". Esto no es cierto, tuve el mismo problema y lo arreglé escribiendo 'localhost'. Gracias por el consejo.
Marco Sulla
1
¡Ah, ja! Sabía que SABÍA la contraseña. Mezzanine produce un local_settings.pyarchivo y # Set to empty string for localhost. Not used with sqlite3.está en su. ¡¡¡MENTIRAS!!!
Teewuane
24

Probablemente se deba a que su script se está ejecutando bajo otro usuario distinto al que está intentando conectarse ( myuser aquí). En este caso, la autenticación de pares fallará. Su solución con HOST: "localhost"funciona porque ya no está usando la autenticación de pares. Sin embargo, es más lento HOST: ""porque en lugar de usar sockets Unix, usa conexiones TCP. De django docs :

Si está utilizando PostgreSQL, de forma predeterminada (HOST vacío), la conexión a la base de datos se realiza a través de sockets de dominio UNIX (líneas 'locales' en pg_hba.conf). Si desea conectarse a través de sockets TCP, configure HOST en 'localhost' o '127.0.0.1' (líneas 'host' en pg_hba.conf). En Windows, siempre debe definir HOST, ya que los sockets de dominio UNIX no están disponibles.

Si desea seguir usando sockets, pg_hba.confse necesitan los ajustes correctos en . El mas simple es:

local   all         all                               trust

mientras comentaba todos los demás local líneas en la configuración. Tenga en cuenta que es necesario volver a cargar postgres para que este cambio surta efecto.

Pero si la máquina de producción multiusuario está en cuestión, es posible que desee utilizar algo más seguro como md5(consulte aquí la explicación de varios métodos de autenticación).

clima
fuente
15

Mejor que confiar plenamente es simplemente configurarlo en md5.

# "local" is for Unix domain socket connections only
local   all         all                           md5
Houman
fuente
6
+1; pero tenga en cuenta que md5 es en general (ligeramente) mejor que la contraseña, ya que enviará un hash en lugar de una contraseña. (Cuando locales que no importa mucho, pero si lo hace por la red con posibles fisgones es significativo.)
dr jimbob
Si PostgreSQL no almacena los hash de contraseña, y no sé si lo hace o no, entonces cualquiera lo suficientemente sofisticado como para escuchar a escondidas su conexión probablemente ejecutará su hash a través de una tabla de arco iris y romperá su seguridad de todos modos.
Lyndsy Simon
1
"md5" es mejor que "confianza", pero lo mejor es usar "peer" y crear un usuario de Linux sin permisos de inicio de sesión, solo para conexiones locales. De esta manera debe proporcionar su contraseña de root para acceder a la base de datos desde local.
Marco Sulla
6

Arreglé esto editando la parte inferior de /etc/postgres/9.1/main/pg_hba.conf para que sea (cambiando md5 a trust; NOTA esto significa que no habrá contraseña de base de datos, que puede que no sea lo que desea)

# TYPE  DATABASE    USER        CIDR-ADDRESS          METHOD

# "local" is for Unix domain socket connections only
local   all         all                               trust
# IPv4 local connections:
host    all         all         127.0.0.1/32          trust
# IPv6 local connections:
host    all         all         ::1/128               trust
vish
fuente
5

Me encontré con el mismo problema, pero quería usar sockets Unix como dijo clime, pero todavía usando el peermétodo. Mapeé mi nombre de usuario del sistema con el nombre de usuario de postgres dentro de pg_hba.conf, que está funcionando con el peermétodo.

Dentro pg_hba.confagregué:

local all all peer map=map-name

Dentro pg_ident.confagregué:

map-name mysystem-username mypostgres-username
ver
fuente