【发布时间】:2021-03-23 07:28:22
【问题描述】:
当我运行代码并输入一个旧的且未经过哈希处理的密码时,它告诉我这是元组,这不是问题,但是当我尝试验证哈希密码时,我发现我的密码错误所以我想知道我的代码有什么问题。我是 python 新手,对 mysql 没有超级经验,但我认为问题在于我如何选择散列密码并执行 if 语句。
'''
from flask import Flask, render_template, request, redirect, url_for, session
from flask_mysqldb import MySQL
from passlib.hash import sha256_crypt
import MySQLdb.cursors
import re
import hashlib
import os
salt = os.urandom(32)
app = Flask(__name__)
app.secret_key = 'ý{Hå<\x95ùã\x96.5Ñ\x01O<!Õ¢\xa0\x9fR"¡¨'
# Enter your database connection details below
app.config['MYSQL_HOST'] = 'localhost'
app.config['MYSQL_USER'] = 'root'
app.config['MYSQL_PASSWORD'] = ''
app.config['MYSQL_DB'] = 'pythonlogin'
# Intialize MySQL
mysql = MySQL(app)
@app.route('/pythonlogin/', methods=['GET', 'POST'])
def login():
# Output message if something goes wrong...
msg = ''
# Check if "username" and "password" POST requests exist (user submitted form)
if request.method == 'POST' and 'username' in request.form and 'password' in request.form:
# Create variables for easy access
username = request.form['username']
password = request.form['password']
# Check if account exists using MySQL
cursor = mysql.connection.cursor(MySQLdb.cursors.DictCursor)
cursor.execute('SELECT * FROM accounts WHERE username = %s AND password = %s', (username, password,))
# Fetch one record and return result
account = cursor.fetchone()
hashedPass = ('SELECT password FROM accounts WHERE username = %s', (username))
# If account exists in accounts table in out database
if account and sha256_crypt.verify(password, hashedPass):
# Create session data, we can access this data in other routes
session['loggedin'] = True
session['id'] = account['id']
session['username'] = account['username']
# Redirect to home page
return redirect(url_for('home'))
else:
# Account doesnt exist or username/password incorrect
msg = 'Incorrect username/password!'
# Show the login form with message (if any)
return render_template('index.html', msg=msg)
''' 以上是我认为问题出在标签/cmets 的地方,因为我已经按照教程进行学习,现在我尝试在此基础上进行构建,这就是我现在卡住的地方
这就是我如何散列它,我相信它是正确完成的: '''
@app.route('/pythonlogin/register', methods=['GET', 'POST'])
def register():
# Output message if something goes wrong...
msg = ''
# 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 'email' in request.form:
# Create variables for easy access
username = request.form['username']
password = sha256_crypt.encrypt(request.form['password']) #Sha 256 encryptering med hash och salt
email = request.form['email']
# Check if account exists using MySQL
cursor = mysql.connection.cursor(MySQLdb.cursors.DictCursor)
cursor.execute('SELECT * FROM accounts WHERE username = %s', (username,))
account = cursor.fetchone()
# If account exists show error and validation checks
if account:
msg = 'Account already exists!'
elif not re.match(r'[^@]+@[^@]+\.[^@]+', email):
msg = 'Invalid email address!'
elif not re.match(r'[A-Za-z0-9]+', username):
msg = 'Username must contain only characters and numbers!'
elif not username or not password or not email:
msg = 'Please fill out the form!'
else:
# Account doesnt exists and the form data is valid, now insert new account into accounts table
cursor.execute('INSERT INTO accounts VALUES (NULL, %s, %s, %s)', (username, password, email,))
mysql.connection.commit()
msg = 'You have successfully registered!'
'''
我可以在数据库中看到用户使用散列和加盐密码注册。 感谢您的帮助:)
【问题讨论】:
-
这是错误的:
cursor.execute('SELECT * FROM accounts WHERE username = %s AND password = %s', (username, password,))- 这不应该匹配并且不会返回任何数据。不要搜索加密的密码;它可以散列到不同的值。仅使用 .verify 来检查它们是否等效。 -
哦,好的,非常感谢乔的回复,那我该如何检查输入的密码是否与加密的密码匹配?
-
这就是`if account and sha256_crypt.verify(password, hashedPass):`在第一个代码示例中所做的事情
-
哦,是的,我知道,我对这个问题的表述很糟糕,我编辑了你指出的代码:'SELECT * FROM accounts WHERE username = %s', (username))' 但它仍然没有'不起作用,但它给了我另一个错误消息“并非所有参数都在字节格式化期间转换”所以仍然有问题,我猜它与帐户变量有关,因为我不确定它的作用。必须将用户连接到它,否则它只会查看密码是否正确?
-
我发现当我执行 'SELECT password FROM accounts WHERE username = %s', (username) 时,它实际上并没有像我想的那样选择加密的密码,而是分配给那个确切的字符串.
标签: python mysql verification passlib