Frage Djangos selb.client.login (...) funktioniert nicht in Komponententests


Ich habe Benutzer für meine Komponententests auf zwei Arten erstellt:

1) Erstellen Sie ein Fixture für "auth.user", das ungefähr so ​​aussieht:

    { 
        "pk": 1, 
        "model": "auth.user", 
        "fields": { 
            "username": "homer", 
            "is_active": 1, 
            "password": 
"sha1$72cd3$4935449e2cd7efb8b3723fb9958fe3bb100a30f2", 
            ... 
        } 
    }

Ich habe die scheinbar unwichtigen Teile weggelassen.

2) Benutze 'create_user' in der setUp-Funktion (obwohl ich lieber behalten würde) alles in meiner Spielklasse):

def setUp(self): 
       User.objects.create_user('homer', 'ho...@simpson.net', 'simpson') 

Beachten Sie, dass das Passwort in beiden Fällen simpson ist.

Ich habe überprüft, dass diese Information immer wieder korrekt in die Testdatenbank geladen wird. Ich kann das Benutzerobjekt mit User.objects.get greifen. Ich kann mit 'check_password' überprüfen, ob das Passwort korrekt ist. Der Benutzer ist aktiv.

Ausnahmsweise wird jedoch self.client.login (username = 'homer', password = 'simpson') fehlschlagen. Ich bin verblüfft, warum. Ich denke, ich habe jede einzelne Internet-Diskussion dazu gelesen. Kann jemand helfen?

Der Login-Code in meinem Unit-Test sieht folgendermaßen aus:

    login = self.client.login(username='homer', password='simpson') 
    self.assertTrue(login) 

Vielen Dank.


53
2018-04-11 23:17


Ursprung


Antworten:


Der Code, der nicht funktioniert:

from django.contrib.auth.models import User
from django.test import Client

user = User.objects.create(username='testuser', password='12345')

c = Client()
logged_in = c.login(username='testuser', password='12345')

Warum funktioniert es nicht?

In dem obigen Ausschnitt, wenn der User erstellt wird, ist der tatsächliche Passwort-Hash-Wert festgelegt 12345. Wenn der Client das anruft login Methode, der Wert der password Streit, 12345, wird durch die Hash-Funktion übergeben, was zu etwas wie

hash('12345') = 'adkfh5lkad438....'

Dies wird dann mit dem Hash verglichen, der in der Datenbank gespeichert ist, und dem Client wird der Zugriff verweigert, weil 'adkfh5lkad438....' != '12345'

 Die Lösung

Das Richtige ist, rufen Sie die set_password Funktion, die die angegebene Zeichenfolge durch die Hash-Funktion übergibt und das Ergebnis speichert User.password.

Zusätzlich nach dem Anruf set_password wir müssen das aktualisierte speichern User Objekt in der Datenbank:

user = User.objects.create(username='testuser')
user.set_password('12345')
user.save()

c = Client()
logged_in = c.login(username='testuser', password='12345')

69
2017-10-23 04:11



Ein einfacherer Weg ist es zu benutzen force_login, neu in Django 1.9.

force_login(user, backend=None)

Beispielsweise:

class LoginView(TestCase):
    def setUp(self):
        self.client.force_login(User.objects.get_or_create(username='testuser')[0])

20
2017-09-28 09:07



Prüfe das django.contrib.sessions wird hinzugefügt INSTALLED_APPS weil client.login() prüft, ob es falsch ist und wird immer false zurückgeben, wenn dies nicht der Fall ist:

https://docs.djangoproject.com/es/1.9/topics/http/sessions/#enabling-sessions


5
2018-01-13 19:50



Können Sie wie folgt überprüfen,

from django.test import TransactionTestCase, Client

class UserHistoryTest(TransactionTestCase):
    self.user = User.objects.create(username='admin', password='pass@123', email='admin@admin.com')
    self.client = Client() # May be you have missed this line

    def test_history(self):
        self.client.login(username=self.user.username, password='pass@123')
        # get_history function having login_required decorator
        response = self.client.post(reverse('get_history'), {'user_id': self.user.id})
        self.assertEqual(response.status_code, 200)

Dieser Testfall hat für mich funktioniert.


3
2017-10-12 06:17



Wenn noch jemand dem folgt, denke ich, dass die Attribute 'is_staff' und 'is_active' für die erfolgreiche Anmeldung auf True gesetzt werden sollten ......

self.user = User.objects.create(username='testuser',password='pwd',is_active=1,is_staff=1)


-3
2017-11-14 10:38