Conexão do Django ao PostgreSQL: “Falha na autenticação de pares”

120
OperationalError at /admin/

FATAL:  Peer authentication failed for user "myuser"

Este é o erro que estou recebendo quando tento acessar meu site de administração do Django. Eu estava usando o banco de dados MySQL não há problema. Eu sou novo no PostgreSQL, mas decidi mudar porque o host que planejo usar para este projeto não possui MySQL.

Portanto, achei que poderia passar pelo processo de instalação do PostgreSQL, executar ae syncdbestar pronto.

O problema é que parece que não consigo conectar meu aplicativo ao banco de dados. Posso fazer login no PostgreSQL via linha de comando ou aplicativo de desktop que baixei. Apenas não no script.

Além disso, eu posso usar manage.py shellpara acessar o db muito bem.

Alguma ideia?

The Brewmaster
fonte

Respostas:

217

Dei uma olhada na exceção, notei que tinha a ver com minhas configurações de conexão. Voltei para settings.py e vi que eu não tinha uma configuração de host. Adicione localhoste pronto.

Meu settings.py não tinha um banco de dados HOST para MySQL, mas eu precisava adicionar um para o PostgreSQL funcionar.

No meu caso, eu adicionei localhostà HOSTconfiguração e funcionou.

Aqui está a DATABASESseção do meu 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
    } 
}
The Brewmaster
fonte
5
considere mover a solução da sua pergunta para a sua resposta (e aceitá-la). Dessa forma, a pergunta continuará sendo uma pergunta e terá uma resposta adequada. BTW: bom trabalho! :-)
Piotr Nowicki
3
Tive o mesmo problema com um aplicativo Rails, e era a mesma solução - o host precisava ser configurado config/database.yml- ou seja, naquele arquivo eu precisava adicionar a linha host: localhost(ou onde quer que você esteja, o servidor do postgres - o meu era local)
jefflunt
7
Quando o HOST está em branco, o Django tenta se conectar ao banco de dados usando soquetes UNIX. Por outro lado, quando o HOST é "host local", ele se conecta via TCP / IP ao 127.0.0.1. Provavelmente, você pg_hba.confestá configurado para impedir que usuários comuns se conectem através de soquetes UNIX, mas permite que eles usem TCP / IP no host local.
Jim Garrison
3
A documentação ( docs.djangoproject.com/en/1.6/ref/settings/#host ) está: "HOST [...] Uma seqüência vazia significa localhost". Isso não é verdade, tive o mesmo problema e o corrigi escrevendo 'localhost'. Obrigado pela dica.
Marco Sulla
1
Ah HA! Eu sabia que sabia a senha. O mezanino produz um local_settings.pyarquivo e o # Set to empty string for localhost. Not used with sqlite3.está no deles. MENTIRAS!!!
Teewuane
23

Provavelmente porque seu script está sendo executado sob outro usuário que não aquele com o qual você está tentando se conectar ( myuser aqui). Nesse caso, a autenticação de mesmo nível falhará. Sua solução HOST: "localhost"funciona porque você não está mais usando a autenticação de mesmo nível. No entanto, é mais lento do que HOST: ""porque, em vez de usar soquetes unix, você usa conexões TCP. Dos documentos do django :

Se você estiver usando o PostgreSQL, por padrão (HOST vazio), a conexão com o banco de dados é feita através de soquetes de domínio UNIX (linhas 'locais' em pg_hba.conf). Se você deseja se conectar através de soquetes TCP, defina HOST como 'localhost' ou '127.0.0.1' (linhas 'host' em pg_hba.conf). No Windows, você sempre deve definir HOST, pois os soquetes de domínio UNIX não estão disponíveis.

Se você quiser continuar usando soquetes, pg_hba.confsão necessárias configurações corretas . O mais simples é:

local   all         all                               trust

enquanto comenta todas as outras locallinhas na configuração. Observe que é necessário recarregar o postgres para que essa alteração entre em vigor.

Mas se a máquina de produção multiusuário estiver em questão, convém usar algo mais seguro como md5(veja aqui a explicação de vários métodos de autenticação).

clima
fonte
14

Melhor do que confiar totalmente, basta configurá-lo para MD5.

# "local" is for Unix domain socket connections only
local   all         all                           md5
Houman
fonte
5
+1; mas observe que o md5 geralmente é (ligeiramente) melhor que a senha, pois enviará um hash em vez de uma senha. (Quando local, ele não importa muito, mas se a fazê-lo através da rede com possíveis bisbilhoteiros é significativo.)
dr jimbob
Se o PostgreSQL não saltar hashes de senhas - e eu não sei se isso ocorre ou não -, alguém sofisticado o suficiente para realmente escutar sua conexão provavelmente executará seu hash em uma tabela do arco-íris e quebrará sua segurança de qualquer maneira.
22612 Lyndsy Simon
"md5" é melhor que "trust", mas o melhor é usar "peer" e criar um usuário Linux sem permissões de login, apenas para conexões locais. Dessa forma, você deve fornecer sua senha root para acessar o banco de dados local.
Marco Sulla
6

Corrigi isso corrigindo a parte inferior do arquivo /etc/postgres/9.1/main/pg_hba.conf (alterando md5 para trust; NOTE isso significa que não haverá senha do banco de dados, o que pode não ser o que você deseja)

# 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
fonte
5

Eu apenas me deparei com o mesmo problema, mas queria usar soquetes unix como o clime disse, mas ainda usando o peermétodo. Mapeei meu nome de usuário do sistema com o nome de usuário postgres dentro do pg_hba.conf, que está funcionando com o peermétodo

Dentro pg_hba.confeu adicionei:

local all all peer map=map-name

Dentro pg_ident.confeu adicionei:

map-name mysystem-username mypostgres-username
visto
fonte