Python Flask用户登录-检查用户是否存在

Python Flask用户登录-检查用户是否存在,python,mysql,flask,login,Python,Mysql,Flask,Login,我已经为我的flask应用程序实现了登录,当我使用正确的凭据登录用户时,它会工作,但是当我尝试使用不存在的用户登录时,我会收到以下错误消息: TypeError:“非类型”对象不可下标 我如何修复此问题以确保有一个将返回消息而不是错误的签入 从错误日志判断,如果光标找不到用户,它似乎不会返回None。使用Flask的调试功能在找不到用户时告知数据的值,然后更新if语句以获得正确的值。如果你想偷懒,你可以键入If data['password']。从错误日志判断,如果找不到用户,光标似乎不会返回N

我已经为我的flask应用程序实现了登录,当我使用正确的凭据登录用户时,它会工作,但是当我尝试使用不存在的用户登录时,我会收到以下错误消息:

TypeError:“非类型”对象不可下标

我如何修复此问题以确保有一个将返回消息而不是错误的签入


从错误日志判断,如果光标找不到用户,它似乎不会返回
None
。使用Flask的调试功能在找不到用户时告知数据的值,然后更新if语句以获得正确的值。如果你想偷懒,你可以键入
If data['password']

从错误日志判断,如果找不到用户,光标似乎不会返回
None
。使用Flask的调试功能在找不到用户时告知数据的值,然后更新if语句以获得正确的值。如果你想偷懒,你可以键入
If数据['password']

解决方案 问题是,即使在数据库中找不到用户名,您也试图获取“密码”。换句话说,如果找不到用户名,您将得到一个空的游标对象。 您可以将代码更改为:

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        username = request.form['username']
        usr_entered = request.form['password']
    cursor = cnx.cursor(dictionary=True, buffered=True)
    cursor.execute("SELECT * FROM users WHERE username =%s", [username])
    if cursor is not None:
        data = cursor.fetchone()
        try:
            password = data['password']
        except Exception:
            error = 'Invalid Username or Password'
            return render_template('login.html', error=error)

        if bcrypt.checkpw(usr_entered.encode('utf-8'), password.encode('utf-8')):
            app.logger.info('Password Matched')
            session['logged_in'] = True
            session['username'] = username

            flash('You are now logged in', 'success')
            cursor.close()
            return redirect(url_for('dashboard'))
        

        else:
            error = 'Invalid Username or Password'
            return render_template('login.html', error=error)

    else:
        error = 'Invalid Username or Password'
        return render_template('login.html', error=error)

    return render_template('login.html')
这是解决问题的一种方法。你可以用if语句来解释它。我还将
cursor.close()
移动到
返回重定向(url\u用于('dashboard'))
之前。在您的版本中,无法访问
游标.close()

附加信息 另一个安全措施是永远不要告诉对方用户名/密码的哪一部分出错。

解决方案 问题是,即使在数据库中找不到用户名,您也试图获取“密码”。换句话说,如果找不到用户名,您将得到一个空的游标对象。 您可以将代码更改为:

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        username = request.form['username']
        usr_entered = request.form['password']
    cursor = cnx.cursor(dictionary=True, buffered=True)
    cursor.execute("SELECT * FROM users WHERE username =%s", [username])
    if cursor is not None:
        data = cursor.fetchone()
        try:
            password = data['password']
        except Exception:
            error = 'Invalid Username or Password'
            return render_template('login.html', error=error)

        if bcrypt.checkpw(usr_entered.encode('utf-8'), password.encode('utf-8')):
            app.logger.info('Password Matched')
            session['logged_in'] = True
            session['username'] = username

            flash('You are now logged in', 'success')
            cursor.close()
            return redirect(url_for('dashboard'))
        

        else:
            error = 'Invalid Username or Password'
            return render_template('login.html', error=error)

    else:
        error = 'Invalid Username or Password'
        return render_template('login.html', error=error)

    return render_template('login.html')
这是解决问题的一种方法。你可以用if语句来解释它。我还将
cursor.close()
移动到
返回重定向(url\u用于('dashboard'))
之前。在您的版本中,无法访问
游标.close()

附加信息
另一个安全措施是永远不要通知此人用户名/密码的哪一部分出错。

你能从回溯中发布更多信息吗?至少回溯显示了一条错误行。仅供参考:这是您的错误源-
x=None;打印(x['key'])
您可以发布回溯中的更多信息吗?至少回溯显示了一条错误行。仅供参考:这是您的错误源-
x=None;打印(x['key'])
我不确定如何调试,我使用了app.debug=True,但是当光标值不正确时,我看不到它是什么。您可以添加
导入pdb;pdb.set_trace()
并按
n
在控制台上调试下一行。我不确定如何调试,我使用了app.debug=True,但是我看不到不正确时光标值是什么。您可以添加
导入pdb;pdb.设置_trace()
并按
n
在控制台上调试下一行。