提问者:小点点

带有SQL连接的Python Flask


from flask import Flask, render_template, request, redirect, url_for, session
from flask_mysqldb import MySQL
from cryptography.fernet import Fernet
import MySQLdb.cursors
import bcrypt

app = Flask(__name__)
app.secret_key = 'your secret key'


# Enter your database connection details below
app.config['MYSQL_HOST'] = 'host'
app.config['MYSQL_USER'] = 'root'
app.config['MYSQL_PASSWORD'] = 'password'
app.config['MYSQL_DB'] = 'pythonlogin'

mysql = MySQL(app)

@app.route('', methods=['GET', 'POST'])
def password_reset():
    msg = 'asd'
    # Check if "username", "password" and "email" POST requests exist (user submitted form)
    if request.method == 'POST' and 'username' in request.form and 'password' in request.form and 'new_password' in request.form and 'email' in request.form:
        # Create variables for easy access
        username = request.form['username']
        password = request.form['password']
        new_password = request.form['new_password']
        email = request.form['email']

        #check if the account exist in the database
        cursor = mysql.connection.cursor(MySQLdb.cursors.DictCursor)
        cursor.execute( "SELECT * FROM accounts WHERE username = %s", (username,))
        account = cursor.fetchall()

        #if the account exist in database
        #the code goes in here
        if account:
            if account['username'] == session['username']:
                salt = bcrypt.gensalt(rounds=16)
                hash_password = bcrypt.hashpw(new_password.encode(), salt)

                sql = "UPDATE accounts SET password = %s WHERE username = %s "
                val = (hash_password, username)
                cursor.execute(sql, val)

                mysql.connection.commit()

                msg = "You have successfully changed the password! "

    elif request.method == 'POST':
        # Form is empty... (no POST data)
        return 'Please fill out the form!'
        # Show registration form with message (if any)

    return render_template('password_reset.html', msg=msg)

嗨,我正在使用SQL连接来做这件事,我正在尝试做的是重置用户的密码,其中用户输入他们的用户名,旧密码,新密码和电子邮件。 然后我尝试根据用户在表单中输入的内容获取用户信息。

例如,用户在表单中输入'john',表单用于检查数据库中是否存在用户名'john',如果数据库中存在'john',我的python代码应该用用户在表单中输入的新密码替换数据库中的旧密码

我所做的代码未能将数据库中的用户名与用户在表单中输入的内容进行比较。 请帮帮忙


共2个答案

匿名用户

我想你需要修改一下你的代码

该方法获取查询结果集的所有(或所有剩余)行,并返回元组列表。 如果没有更多的行可用,则返回一个空列表。 因此fetchall将给出类似[(),()]的内容。您需要获取第一个元素,

或者您可以使用cursor.fetchOne(),它将给您一条记录或一条记录都不给。您将得到这样的结果,tuple()的as行,类似于

(1,'emma‘,'emma@pynative.com','asdasd',)

您需要设置正确的索引才能从数据库访问您的用户名,例如account_name=account[your_acccount_name_index]

并匹配account_name==username==session['username']

匿名用户

这是一种非常古老的应用程序(硬编码SQL语句。。) 一般来说,这不是开发现代flask应用程序的推荐方式。 有许多3rd packages(文档齐全)可以使您的应用程序非常容易开发,健壮,甚至更安全。 我就给大家推荐那些常用的第三包:

    用于sql和模型的
  • flask-sqlalchemy..
  • Flask-WTFormsforms
  • flask-login用于身份验证/注册

在审阅的代码下面:

from flask import Flask, flash, render_template, request, redirect, url_for, session
from flask_mysqldb import MySQL
from cryptography.fernet import Fernet
import MySQLdb.cursors
import bcrypt
import re 

app = Flask(__name__)
app.secret_key = 'your secret key'

# Enter your database connection details below
app.config['MYSQL_HOST'] = 'host'
app.config['MYSQL_USER'] = 'root'
app.config['MYSQL_PASSWORD'] = 'password'
app.config['MYSQL_DB'] = 'pythonlogin'

mysql = MySQL(app)

# add route name 
@app.route('/reset-password', methods=['GET', 'POST'])
def password_reset():
    if request.method == 'POST':

        # since username and email are uniques for any given account, you can use one of them or 
        # even better, using only the 'username' field, the user can enter his username or email
        # and then check wether the input of 'username' field is a username or an email (with 
        # simple regexp or 3rd package) so you can make the form more compact and more UI/UX friendly. 

        username     = request.form['username']  # as label for this field : "enter your usernme or email")
        password     = request.form['password']
        new_password = request.form['new_password']
        email        = request.form['email']
        
        # flag to check errors
        error = None

        # check if the 'reset password' form is filled and all parameters are posted
        if not username:
            error = "Username is required."
        elif not password:
            error = "Password is required."
        elif not new_password:
            error = "New Password is required."
        elif not email:
            error = "Email is required."
        elif not re.search('^[a-z0-9]+[\._]?[a-z0-9]+[@]\w+[.]\w{2,3}$', email):
            error = "Email is not valid."


        if error is None:
            # check if the account exist in the database
            cursor = mysql.connection.cursor(MySQLdb.cursors.DictCursor)
            cursor.execute( "SELECT * FROM accounts WHERE username = %s OR email = %s", (username, email))
            account = cursor.fetchone()  # to get the first record

            # if the account exist in database
            # the code goes in here
            if account:
                salt = bcrypt.gensalt(rounds=16)
                hash_password = bcrypt.hashpw(new_password.encode(), salt)
                
                sql = "UPDATE accounts SET password = %s WHERE username = %s "
                val = (hash_password, username)
                cursor.execute(sql, val)
                
                mysql.connection.commit()

                flash("You have successfully changed the password!", "success")

                if account['username'] == session['username']:  # if the user is already logged in
                    return redirect(url_for("dashbord"))  # redirect to dashboard
                return redirect(url_for("auth.login"))  # if not logged in, redirect him to login page 

            else:
                error = "The username / email don't match our records."

        # you don't need to pass the error / success mesaages to render_templte, use flash()
        # you can add an extra parmeter 'success' or 'error' to make difference and disply 
        # properly the right 'alert' message (if you re using Bootstrap for e.g)
        flash(error, 'error')

    return render_template('password_reset.html')

在主布局中使用下面的代码可根据flash()消息的类别成功错误显示这些消息

  {% with messages = get_flashed_messages(with_categories=true) %}
    {% if messages %}
      {% for category, message in messages %}
      <div class="alert alert-{% if category == 'error' %}danger{% else %}{{ category }}{% endif %} alert-dismissible fade show rounded-0" role="alert">
        <strong class="text-uppercase">{{ category }}!</strong> {{ message }}
        <button type="button" class="close" data-dismiss="alert" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      {% endfor %}
    {% endif %}
  {% endwith %}

最后,有许多github存储库,用于启动flask应用程序,您可以在下一个项目中参考主题,例如:https://github.com/hack4impact/flask-base