2012-09-14 10 views
6

Ho creato un utente quando si utilizza il comando syncdb e si registra perfettamente. Ma quando creo un utente da Django admin, esso viene creato correttamente, ma fa sì che l'errore quando si accede in ottengo l'errore:.Perché la password utente non viene sottoposta a hash in admin django?

Unknown password hashing algorithm 'password'. Did you specify it in the PASSWORD_HASHERS setting? 

Qual è il problema? come posso risolverlo in modo che la password venga automaticamente crittografata quando si salva l'utente in admin?

risposta

0

Django non memorizza le password come testo normale. Prima li salda e loro memorizza l'hash. Quindi, quando l'utente effettua il login, Django applica la stessa funzione di hash agli input degli utenti e poi confronta i due hash - dagli input degli utenti e ciò che è memorizzato nel db.

Tuttavia, per rendere le cose più flessibili, Django non memorizza gli hash delle password, ma lo fa, ma in aggiunta memorizza anche l'algoritmo con cui è stato generato l'hash. Immagina questo scenario: usi la funzione hash X per generare gli hash delle password, ma poi ti rendi conto che quella funzione non è più sicura per qualsiasi motivo e passi alla funzione di hashing Y. Questo comunque è un problema perché al punto, l'hash della password di chiunque è memorizzato usando la funzione X, non sarebbero più in grado di effettuare il login. Ecco perché Django memorizza anche il metodo con cui è stato generato l'has, oltre al valore hash stesso. È qui che entra in gioco l'impostazione PASSWORD_HASHERS. Il fatto che Django memorizzi il metodo con cui viene generato l'hash nel db, quando legge il valore, in realtà non dice a Django come eseguire la funzione di hash stessa. Quindi PASSWORD_HASHERS è un po 'come un mappatore tra la funzione di hashing di Python (in realtà una classe ma comunque ...) e il valore memorizzato nel db.

Quindi torna alla tua domanda. Il messaggio di errore indica che Django non è a conoscenza della funzione di hashing password che è stata utilizzata per memorizzare l'hash della password nel database, o almeno non è nello PASSWORD_HASHERS.

Posso pensare a un paio di motivi per cui ciò potrebbe accadere.

  • Assicurarsi che poi si fa syncdb, utilizza lo stesso settings.py file come quando si esegue il server per accedere al admin. Potrebbe essere il caso che vengano utilizzate impostazioni diverse.

  • Tuttavia, gli sviluppatori di solito non modificano PASSWORD_HASHERS nello settings.py e utilizzano semplicemente il valore predefinito. In tal caso, assicurarsi di utilizzare lo stesso Python con la stessa versione installata di Django quando si esegue syncdb e quando si esegue il server. Se si esegue syncdb in un virtualenv, ad esempio, ed è in esecuzione server in env differenti, le versioni di Django potrebbero essere diverse, quindi potrebbero avere impostazioni diverse per PASSWORD_HASHERS e quindi dove si esegue syncdb, potrebbe essere utilizzata una funzione di hashing che non è definito quando si esegue il server.

+0

Si può leggere di più su come Django memorizza le password in https://docs.djangoproject.com/en/1.4/topics/auth/#how-django-stores-passwords o leggere l'intera pagina per ottenere un una migliore comprensione di come funziona l'autenticazione Django, che include l'autenticazione dell'utente. – miki725

4

Ho incontrato lo stesso problema in una situazione in cui avevo sottoclasse dell'utente del Django, quindi ha creato un modello di amministrazione per esso e usato il modulo di amministrazione Django generato automaticamente per creare un utente.

così ho avuto qualcosa di simile nella mia models.py

class Employee(User): 
    job = models.CharField(max_length=100) 

e questo nella mia amministrazione.py

class EmployeeAdmin(admin.ModelAdmin): 
    pass 
admin.site.register(Employee, EmployeeAdmin) 

Ora Django crea automaticamente un modulo per aggiungere nuovi dipendenti nell'amministratore di Django. Ma quando questo modulo viene utilizzato per creare un utente, la password non verrà affatto cancellata. Quindi, per qualche ragione, Django crea un normale campo di immissione del testo per la password quando il modello è derivato dall'utente incorporato di Django. Non so se avessi lo stesso caso.

Purtroppo non sono riuscito a trovare una soluzione semplice per risolvere questo problema. Non ho idea del perché Django non stia creando automaticamente il campo modulo corretto per la password. Tuttavia, una possibilità potrebbe essere quella di sovrascrivere il modulo automatico con un modulo personalizzato che includa un widget password. Vedi https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.formfield_overrides.

+0

è necessario estendere UserAdmin, non ModelAdmin –

2

Ho riscontrato lo stesso problema mostrato nella risposta Rubino e potrebbe anche essere il tuo problema.

Il problema è accaduto quando ha ereditato il mio modello utente django.contrib.admin.ModelAdmin invece di django.contrib.auth.admin.UserAdmin

Facendo questo, mi è stato bypassando funzionalità utente necesary

2

Soluzione per la password viene memorizzata come testo piuttosto che la password hash è quello di utilizzare UserAdmin da django.contrib.auth.admin invece di ModelAdmin.

from django.contrib.auth.admin import UserAdmin 

class EmployeeAdmin(UserAdmin): 
    pass 

admin.site.register(Employee, EmployeeAdmin) 
Problemi correlati