Nano Hash - криптовалюты, майнинг, программирование

Как передать результат запроса в переменную (в виде строки) с помощью SQLAlchemy?

Итак, у меня есть проблема. Я пытаюсь проверить, действителен ли пароль для простого веб-приложения Flask.

Вот упрощенная версия моего кода:

@app.route('/login', methods=['POST', 'GET'])
def login():

    if request.method == 'POST':

        username = request.form['username']
        password = request.form['password']

    user_password = db.session.query(User.password).filter(User.username == username).first()

    if password != str(user_password):
        return "The password is invalid."
    else:
        return "Login successful."

Но это не работает... Это всегда недействительно, и я думаю, что знаю, почему. Запрос user_password на самом деле не возвращает пароль в виде строки. Если пароль Hello1234, возвращается ("Hello1234",). Мне нужно, чтобы user_password просто получал возвращаемую строку в виде строки, чтобы я мог сравнить ее с пользовательским вводом.

Как я могу это сделать?

10.05.2020

  • использовать user_password[0] - т.е. if password != user_password[0]: Кстати: но вам, возможно, придется проверить, получили ли вы какое-либо значение в user_password, прежде чем использовать [0], потому что вы можете получить пустой результат, а затем [0] выдаст ошибку. if user_password and password != user_password[0]: 10.05.2020
  • Я должен настоятельно призвать вас не сохранять пароли в виде простого текста в вашей базе данных. Пожалуйста, не увековечивайте цикл. 10.05.2020
  • Убедитесь, что вы понимаете тип возвращаемого значения из вызовов функций с цепочкой больших запросов к базе данных. Вы не возвращаете строку, это кортеж со строкой в ​​качестве первого члена. 10.05.2020
  • @sleblanc Я должен сообщить вам, что это ТОЛЬКО ДЛЯ ТЕСТИРОВАНИЯ и для личного проекта, пока я учусь. Это не идет в производство. 10.05.2020
  • вместо .first() вы можете использовать .scalar() для получения скалярного значения в первой строке, в противном случае выберите 0-й элемент в кортеже, используя user_password[0] 10.05.2020

Ответы:


1

Если вы получили кортеж ('Hello1234',), используйте индекс [0], чтобы получить первый элемент из кортежа ('Hello1234',)[0].

if password != user_password[0]:

Кстати: я не знаю, что это дает, когда в базе данных нет пароля - пустой кортеж или None или ошибка повышения, но если это дает пустой кортеж или None, тогда вы должны сначала проверить, есть ли что-то до вы можете использовать [0]

if user_password and password != user_password[0]:
10.05.2020
  • Да, это сработало. 10.05.2020
  • Кстати у меня запрос сначала на поиск юзернейма, если кол-во строк = 0 то юзера нет, если он › 1 то проблема а если он = 1 то юзернейм есть, то следующий шаг — проверить, действителен ли пароль. 10.05.2020
  • вам не нужно проверять, существует ли пользователь, потому что вы должны получить тот же результат, когда вы получите пароль (без first()) и проверите len(user_password) 10.05.2020
  • .first() просто вернет None, когда набор результатов пуст. Примечание: обычно вы хотите использовать .one_or_none(), так как он будет обнаруживать ошибки программирования при неожиданном возврате более одной записи, облегчая отладку, вместо того, чтобы молча отбрасывать дополнительные записи. 10.05.2020
  • @sleblanc Спасибо за это. Я посмотрю на это. 10.05.2020

  • 2

    Когда SQLAlchemy возвращает строку, она никогда не возвращает отдельные значения, а всегда отдельную строку. Поэтому вы должны извлечь значение из строки или сравнить его с кортежем, содержащим те же значения.

    form_username = request.form['username']
    form_password = request.form['password']
    
    row = db.session.query(User.password).filter(User.username == form_username).one_or_none()
    
    if row is None:
        print("You are not part of our secret club")
    
    else:
        crypted_password = row[0]
    
        # def check_password(plaintext, crypted) → bool
    
        if check_password(form_password, crypted_password):
            print("Access granted")
        else:
            print("Don't try to hack me!")
    

    Кроме того, вы можете проверить имя пользователя и пароль за один раз. Этот метод не работает, потому что функция проверки пароля обычно должна знать соль, которая хранится вместе с хэшированным паролем внутри базы данных.

    Вся схема «выберите пользователя, если он существует, затем подтвердите пароль» существует только из-за хранения хешированных паролей с солью, в противном случае вы должны свести к минимуму обращения к базе данных и выполнить всю свою транзакцию за как можно меньшее количество запросов.

    form_username = request.form['username']
    form_password = request.form['password']
    
    row = db.session.query(User.name).filter(
            User.username == form_username,
            User.password == form_password).one_or_none()
    
    if row is None:
        print("Username or password invalid.")
    else:
        print("Welcome aboard, %s.".format(row[0]))
    
    10.05.2020
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..