python - 带有 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代码应该替换数据库中的旧密码和用户在表单中输入的新密码
我所做的代码无法将数据库中的用户名与用户在表单中输入的内容进行比较。请帮忙
解决方案
一般来说,这是做应用程序(硬编码语句......)的非常古老的学校,SQL
而不是推荐的现代flask
应用程序方法。有很多3rd packages
(有据可查的)可以使您的应用程序非常容易开发、健壮甚至更安全。我会向你推荐那些常用的第三个包:
Flask-SQLAlchemy
对于 sql 和模型..Flask-WTForms
对于表格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()
根据它们的类别显示消息success
,error
{% 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">×</span>
</button>
</div>
{% endfor %}
{% endif %}
{% endwith %}
最后,有许多 github 存储库用于入门Flask
应用程序,您可以参考下一个项目的主题,例如:
https ://github.com/hack4impact/flask-base
推荐阅读
- javascript - 几条柏树管道总是挂着,一条柏树管道总是通过
- machine-learning - Random Cut Forest模型评估策略(混淆矩阵、Accuracy和precision_recall_fscore
- html - 如何水平对齐以前垂直对齐的照片?
- jmespath - 使用 JMESPATH 过滤具有 json 值的对象列表
- c# - Cognito .Net C# Forced Password Reset 进入恶性循环
- firebase - 验证 webhook 的云功能域
- ios - 使用 CoreText 绘图时禁用混合
- google-analytics - 如何捕获按钮单击事件标签附近的文本
- r - R : 'Path' 不是内部或外部命令、可运行程序或批处理文件
- c# - 在哪里可以找到 Microsoft.Windows.Simulator.Common?