sqlite3: login program

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
Astraioz

Hallo,
ich brauche mal wieder eure Hilfe. :D

Ich habe mir ein einfaches Login Programm gebastelt und stoße auf ein Problem.
Wo genau der Fehler liegt weiß ich leider nicht genau..

Hier ein Teil vom Programm:

Code: Alles auswählen

def login(self, entryname, entrypass):
        self.username = self.entryname.get()
        self.passwort = self.entrypass.get()
        query('SELECT password FROM users WHERE name = "'+self.username+'"')
        self.userpass = cursor.fetchone()
        if self.userpass == None:
            print 'Benutzer oder Passwort falsch'
            self.entryname['bg'] = '#FF0000'
            self.entrypass['bg'] = '#FF0000'
        else:
            self.userpass = cursor.fetchone()[0]
            if self.userpass == self.passwort:
                print 'eingeloggt'
            else:
                print 'Benutzer oder Passwort falsch'
                self.entryname['bg'] = '#FF0000'
                self.entrypass['bg'] = '#FF0000'
Egal was ich mache ich bekomme immer die Fehlermeldung:

Code: Alles auswählen

TypeError: 'NoneType' object is not subscriptable

Ich habe ja extra versucht, dass wenn es den eingegebenen Benutzernamen nicht gibt, dass das Programm abbricht.
Wo liegt das Problem?
LG
Astraioz
BlackJack

@Astraioz: Das liegt daran, dass Du nicht zweimal für die gleiche Anfrage `fetchone()` aufrufen kannst. Also Du kannst schon, aber beim ersten Aufruf wird die erste Zeile von der Abfrage zurückgegeben und beim zweiten mal die zweite. Die zweite ist aber immer `None`, zumindest wenn die Benutzernamen eindeutig sind.

Der Code ist ungünstig strukturiert, weil der Quelltext für den Fehlerfall zweimal dort steht.

`cursor` kommt hier einfach so aus dem nichts — das sollte nicht sein. Wenn es sich nicht um Konstanten handelt, sollten Werte in Methoden entweder als Argumente oder über das Objekt (also letztendlich ja auch über ein Argument) in die Methode kommen.

Edit: Der Benutzername sollte, wie andere „unsichere” Werte, nicht per Zeichenkettenformatierung in SQL-Anfragen gelangen. Das ist eine riesige Sicherheitslücke. Dafür gibt es Platzhalter in SQL und das zweite Argument von `execute()`, wo man die Werte für die Platzhalter übergeben kann.
Astraioz

@BlackJack: Ok mit der Sicherheitslücke habe ich verstanden das werde ich sofort ändern.

Haste eine Lösung für das fetchone() ?
Wäre sehr nett. Ich setzte mich trotzdem selber nochmal dran.

Danke für die schnelle Antwort.
LG
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Astraioz hat geschrieben:Haste eine Lösung für das fetchone() ?
Das fetchone nur einmal ausführen und das Ergebnis an einen Namen binden.
Das Leben ist wie ein Tennisball.
Astraioz

Problem gelöst.
Falls es andere interessiert:

Einfach in der Zeile

Code: Alles auswählen

if self.userpass == self.passwort:
ein [0] dran geschoben

Code: Alles auswählen

if self.userpass[0] == self.passwort:
Antworten