Połączenie Django z PostgreSQL: „Uwierzytelnienie peera nie powiodło się”

121
OperationalError at /admin/

FATAL:  Peer authentication failed for user "myuser"

To jest błąd, który otrzymuję, kiedy próbuję dostać się do mojej strony administratora Django. Używałem bazy danych MySQL bez problemu. Jestem nowy w PostgreSQL, ale zdecydowałem się na zmianę, ponieważ host, którego docelowo planuję użyć w tym projekcie, nie ma MySQL.

Dlatego pomyślałem, że mógłbym przejść przez proces instalacji PostgreSQL, uruchomić syncdbi mieć wszystko ustawione.

Problem polega na tym, że nie mogę połączyć mojej aplikacji z bazą danych. Mogę zalogować się do PostgreSQL za pomocą wiersza poleceń lub aplikacji komputerowej, którą pobrałem. Po prostu nie w scenariuszu.

Mogę również użyć, manage.py shellaby uzyskać dostęp do bazy danych dobrze.

jakieś pomysły?

Brewmaster
źródło

Odpowiedzi:

219

Rzuciłem okiem na wyjątek, zauważyłem, że ma to związek z ustawieniami połączenia. Wróciłem do settings.py i zobaczyłem, że nie mam konfiguracji hosta. Dodaj localhosti voila.

Mój settings.py nie miał bazy danych HOST dla MySQL, ale musiałem ją dodać, aby PostgreSQL działał.

W moim przypadku dodałem localhostdo HOSTustawienia i zadziałało.

Oto DATABASESsekcja z my 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
    } 
}
Brewmaster
źródło
5
możesz rozważyć przeniesienie rozwiązania ze swojego pytania do odpowiedzi (i zaakceptowanie jej). W ten sposób pytanie pozostanie pytaniem i będzie miało prawidłowo udzieloną odpowiedź. BTW: dobra robota! :-)
Piotr Nowicki
3
Miałem ten sam problem z aplikacją Rails i to było to samo rozwiązanie - host musiał być skonfigurowany config/database.yml- to znaczy w tym pliku musiałem dodać linię host: localhost(lub gdziekolwiek jest serwer postgres - mój był lokalny)
jefflunt
7
Gdy HOST jest pusty, Django próbuje połączyć się z bazą danych przy użyciu gniazd UNIX. Z drugiej strony, gdy HOST to „localhost”, łączy się przez TCP / IP z 127.0.0.1. Prawdopodobnie twoja pg_hba.confkonfiguracja uniemożliwia zwykłym użytkownikom łączenie się przez gniazda UNIX, ale pozwala im przez TCP / IP z lokalnego hosta.
Jim Garrison
3
Dokumentacja ( docs.djangoproject.com/en/1.6/ref/settings/#host ) kłamie: „HOST [...] Pusty ciąg oznacza localhost”. To nieprawda, miałem ten sam problem i naprawiłem go pisząc „localhost”. Dziękuję za wskazówkę.
Marco Sulla
1
Ah HA! Wiedziałem, że ZNAŁEM hasło. Mezzanine tworzy local_settings.pyplik i # Set to empty string for localhost. Not used with sqlite3.znajduje się w ich. KŁAMSTWA !!!
teewuane
24

Dzieje się tak prawdopodobnie dlatego, że Twój skrypt jest uruchomiony przez innego użytkownika niż ten, z którym próbujesz się połączyć ( tutaj myuser ). W takim przypadku uwierzytelnianie partnera zakończy się niepowodzeniem. Twoje rozwiązanie HOST: "localhost"działa, ponieważ nie używasz już uwierzytelniania równorzędnego. Jest to jednak wolniejsze niż HOST: ""dlatego, że zamiast używać gniazd unix, używasz połączeń TCP. Z dokumentów django :

Jeśli używasz PostgreSQL, domyślnie (pusty HOST), połączenie z bazą danych odbywa się przez gniazda domeny UNIX (linie „lokalne” w pg_hba.conf). Jeśli chcesz łączyć się przez gniazda TCP, ustaw HOST na 'localhost' lub '127.0.0.1' (linie 'host' w pg_hba.conf). W systemie Windows należy zawsze definiować HOST, ponieważ gniazda domeny UNIX nie są dostępne.

Jeśli chcesz nadal używać gniazd, pg_hba.confpotrzebne są prawidłowe ustawienia . Najprostszy to:

local   all         all                               trust

podczas komentowania wszystkich innych locallinii w config. Pamiętaj, że aby zmiana zaczęła obowiązywać, potrzebne jest przeładowanie postgresów.

Ale jeśli chodzi o maszynę produkcyjną dla wielu użytkowników, możesz chcieć użyć czegoś bezpieczniejszego, takiego jak md5(zobacz tutaj wyjaśnienie różnych metod uwierzytelniania).

klimat
źródło
15

Lepszym niż pełne zaufanie jest po prostu ustawienie md5.

# "local" is for Unix domain socket connections only
local   all         all                           md5
Houman
źródło
6
+1; ale pamiętaj, że md5 jest generalnie (nieco) lepsze niż hasło, ponieważ wyśle ​​skrót zamiast hasła. (Gdy lokalnie to nie ma większego znaczenia; ale jeśli robisz to przez sieć z możliwymi podsłuchiwaczami, jest to znaczące).
dr jimbob
Jeśli PostgreSQL nie soli skrótów haseł - a ja nie wiem, czy tak jest, czy nie - to każdy wystarczająco wyrafinowany, aby faktycznie podsłuchiwać twoje połączenie, prawdopodobnie przeprowadzi twój hash przez tęczową tabelę i mimo wszystko złamie twoje bezpieczeństwo.
Lyndsy Simon
1
„md5” jest lepsze niż „zaufanie”, ale najlepiej jest użyć „peer” i utworzyć użytkownika Linuksa bez uprawnień logowania, tylko dla połączeń lokalnych. W ten sposób musisz podać hasło roota, aby uzyskać dostęp do bazy danych z lokalnego.
Marco Sulla,
6

Naprawiłem to, edytując dolną część /etc/postgres/9.1/main/pg_hba.conf na (zmieniając md5 na zaufanie; UWAGA oznacza to, że nie będzie hasła do bazy danych, które może nie być tym, czego chcesz)

# 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
źródło
5

Właśnie natknąłem się na ten sam problem, ale chciałem użyć gniazd unix, jak powiedział Clime, ale nadal używając tej peermetody. Zmapowałem moją nazwę użytkownika systemu z postgres-username wewnątrz elementu pg_hba.conf, który działa z peermetodą.

Wewnątrz pg_hba.confdodałem:

local all all peer map=map-name

Wewnątrz pg_ident.confdodałem:

map-name mysystem-username mypostgres-username
widziany
źródło