Невозможно прочитать данные sqlite и сравнить их со строками в python - PullRequest
0 голосов
/ 24 мая 2019

Итак, у меня есть базовый код для простого входа пользователя.

import tkinter as tk
import sqlite3

conn = sqlite3.connect("test")
cur = conn.cursor()
cur.execute("SELECT * FROM user_info")
all_rows = cur.fetchall()
usernames = []
passwords = []
for row in all_rows:
    usernames.append(row[0])
    passwords.append(row[1])
print(usernames)
print(passwords)


class loginApp(tk.Tk):

    def __init__(self):
        tk.Tk.__init__(self)
        self._frame = None
        self.switch_frame(loginPage)

    def switch_frame(self, frame_class):
        new_frame = frame_class(self)
        if self._frame is not None:
            self._frame.destroy()
        self._frame = new_frame
        self._frame.pack()

    def login_check(self, username, password):
        x = username.get()
        y = password.get()
        login_check_bool = False
        for i in range(len(usernames)):
            if x is usernames[i] and y is passwords[i]:
                login_check_bool = True
            else:
                self.switch_frame(badLogin)
                print(x + y)
        if login_check_bool is True:
            self.switch_frame(goodLogin)


class loginPage(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self, master)
        tk.Label(self, text="Login to the Application", font="Arial 20 bold").pack()
        tk.Label(self, text="Username: ", font="Arial 15").pack()
        ownUser = tk.Entry(self, width=24)
        ownUser.pack()
        tk.Label(self, text="Password: ", font="Arial 15").pack()
        ownPass = tk.Entry(self, width=24, show="*")
        ownPass.pack()
        tk.Button(self, text="LOGIN", command=lambda: master.login_check(ownUser, ownPass)).pack()


class goodLogin(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self, master)
        tk.Label(self, text="YOU'RE LOGGED IN!!!").pack()
        tk.Button(self, text="RETRY", command=lambda: master.switch_frame(loginPage)).pack()


class badLogin(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self, master)
        tk.Label(self, text="WRONG!!!").pack()
        tk.Button(self, text="RETRY", command=lambda: master.switch_frame(loginPage)).pack()


if __name__ == "__main__":
    app = loginApp()
    app.mainloop()

Кажется, все работает нормально, но у меня есть одна простая проблема. Кажется, я не могу сравнить значение базы данных, полученное из test-db, со своими паролями и значением имени пользователя. Если я использую тестовый логин с именем пользователя l и паролем l, он работает нормально. Любые решения?

У меня также есть конфигурация sqlite, в которой есть простая таблица в test-db с именами пользователей (varchar (24)) и паролем (varchar (24)). Я не знаю, имеет ли это какое-либо отношение к тому факту, что это не работает. Спасибо!

PS. Извините, выписки для печати предназначены для отладки.

1 Ответ

1 голос
/ 24 мая 2019

"is" - неправильный способ сравнения строк в Python.

Замените эту строку:

if x is usernames[i] and y is passwords[i]:

на

if x == usernames[i] and y == passwords[i]:

И вы должны получитьмимо текущего неправильного поведения (хотя дизайн имеет достаточно проблем, у вас могут быть другие проблемы)

что? Да.Оператор is просто приводит к True, когда оба операнда являются одним и тем же объектом.Если в теле программы есть строка, жестко запрограммированная, существует специфическая для реализации оптимизация, которая интернализует строку, и есть вероятность, что она даст True по сравнению с использованием is - но чтение затем из базы данныхне будет вызывать такое поведение.

Оператор ==, с другой стороны, сравнивает фактическое содержимое строки и является правильным способом сравнения строк или любых других объектов на равенство.

другие вопросы? Много.Чтобы начать с того факта, что вы читаете все содержимое базы данных в двух несвязанных с поиском, некоррелированных структурах памяти, и с этого момента прибегайте к методу поиска, который действительно очень «ручной» по сравнению с поиском в Python или SQLite.и сравните возможности.

То есть вы вводите все логины и пароли БД в два отдельных списка.Вы можете просто выполнить запрос по логину внутри login_check.Если запрос не дал результатов, у вас неверный логин.Если он возвращает один результат, вы продолжаете сравнивать пароль в той же строке.Это достаточно очевидный дизайн для этого приложения.

Изучение безопасности с самого начала Итак, вы изучаете больше вещей и создаете приложения, которые имеют пользовательский интерфейс и работают с базами данных - не нужноне заботиться о безопасности и неприкосновенности частной жизни с правильного пути с сегодняшнего дня: если вы запишите простой пароль в свою базу данных, если она будет просочиться, это станет серьезной неудачей для вас и бременем для всех ваших пользователей - (потому что они могутиспользовать те же пароли в другом месте), поэтому всякий раз, когда вы сохраняете пароль, не торопитесь хранить его с использованием одностороннего криптографического алгоритма, при сравнении паролей вы запускаете тот же односторонний алгоритм для введенного пароля и сравниваете его.значение с тем, что хранится в БД.Если неудачная покупка забирает ваши данные из БД, нет способа вернуть зашифрованные пароли обратно в открытый текст.В Python есть хорошие односторонние криптоалгоритмы в модуле stdlib hashlib.Взгляни туда.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...