过去几个月我一直在为我的节奏游戏社区创建一个网站,我尝试实现一个登录页面,以便用户如果想参加特定的比赛就可以轻松填写锦标赛表格。因此,为了额外的安全性,我尝试使用 cryptography.fernet 作为我的加密方法。但由于某种原因,当我在注册后尝试登录时,即使我使用单个密钥,我的加密用户名也会更改为不同的内容。
这是我当前的脚本。
from flask import Flask, render_template, request,redirect
import tweepy
import sqlite3
import discord
from cryptography.fernet import Fernet
app = Flask(__name__)
main_key = open('key.key', 'rb')
encryptor = Fernet(main_key.read())
@app.route('/', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
usernameInput = request.form['username']
userpassInput = request.form['password']
userInput = str(encryptor.encrypt(usernameInput.encode('utf-8'))) #Encrypts the form from the html
userpass = str(encryptor.encrypt(userpassInput.encode('utf-8')))
db_connect = sqlite3.connect("accounts.db")
cur = db_connect.cursor()
cur.execute("""SELECT * FROM accountsDB WHERE userName=? or accessCode=?""", (userInput, userInput))
userAccountName = cur.fetchone()
print(userInput)
print(userAccountName)
if userAccountName:
if userAccountName[0] == userInput and userAccountName[4] == userpass:
return redirect('/userAccountPage', code=302)
elif userAccountName[0] == userInput and userAccountName[4] != userpass:
return 'Wrong Password'
else:
return 'No user Found'
return render_template('login.html')
@app.route("/registration", methods=['GET', 'POST'])
def registrationPage():
if request.method == 'POST':
username_reg = request.form['username']
userCode_reg = request.form['aime-access-code']
userMaiName_reg = request.form['maimaiIGN']
userpassword_reg = request.form['initialPassword']
enc_username = str(encryptor.encrypt(username_reg.encode('utf-8')))
print(enc_username)
enc_code = str(encryptor.encrypt(userCode_reg.encode('utf-8')))
enc_IGN = str(encryptor.encrypt(userMaiName_reg.encode('utf-8')))
enc_pass = str(encryptor.encrypt(userpassword_reg.encode('utf-8')))
db_connect = sqlite3.connect("accounts.db")
cur = db_connect.cursor()
cur.execute("""INSERT INTO accountsDB(userName, accessCode, maimaiIGN, userPassword) VALUES (?,?,?,?)""",
(enc_username,enc_code,enc_IGN,enc_pass))
db_connect.commit()
return redirect('/', code=302)
return render_template('registration.html')
我找不到任何错误。所以我断定它是 Fernet 的加密方法之间的某种东西。那么我可以使用更好的网站加密方法吗?
您在从数据库存储和检索信息后似乎遇到了正确解密信息的问题。
加密值发生变化的一个可能原因是 Fernet 加密每次调用时都会生成不同的密文,即使使用相同的明文和密钥也是如此。这是由于加密过程中使用了随机初始化向量。
但是由于您不想使用它并想使用一些替代方案,因此我们不会深入探讨。
Flask 提供了 Flask-Login 等扩展,用于用户会话管理和身份验证。我将向您展示它是如何完成的。
from flask import Flask, render_template, request, redirect
from flask_login import UserMixin, login_user, login_required, logout_user, current_user, LoginManager
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
db = SQLAlchemy()
DB_NAME="your_db_name_here.db" # change this your db name.
app.secret_key = 'your_secrate_key_here' #chnage this to a random string.
# Specifing the Path of Database
app.config['SQLALCHEMY_DATABASE_URI'] = f'sqlite:///{DB_NAME}'
db.init_app(app) # Initialise DB
#Databse Schema
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
Username = db.Column(db.String(150), unique=True)
Password = db.Column(db.String(150))
#This Function Runs all The Database
def create_database():
with app.app_context():
if not path.exists(DB_NAME):
db.create_all()
create_database()
# Creates a Main User (Ignored if alredy Initalised)
def create_main_user():
with app.app_context():
user = User.query.filter_by(Username='your_username_here').first()
if not user:
new_baisc_user=User(Username='your_username_here', Password=generate_password_hash('your_password_here'))
db.session.add(new_baisc_user)
db.session.commit()
create_main_user()
#------Steup of Flask-LoginMananger------#
login_manager = LoginManager()
login_manager.login_view = '/login'
login_manager.init_app(app)
#--Connecting LoginManager to Datatbsse--#
#Connect Unique Identifier to LoginManager
@login_manager.user_loader
def load_user(id):
return User.query.get(int(id))
#----------------------------------------#
@app.route("/")
@login_required
def Index():
return f"""
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hello Page</title>
</head>
<body>
<h1>Hello, { current_user }</h1>
</body>
</html>"""
@app.route("/login" , methods=['GET','POST'])
def Login():
if current_user.is_authenticated:
return redirect('/')
if request.method=='POST':
Username = request.form.get('username')
Password = request.form.get('password')
user = User.query.filter_by(Username=Username).first()
if user:
if check_password_hash(user.Password, Password):
login_user(user, remember=True)
return redirect('/')
return """
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Login Page</title>
</head>
<body>
<div>
<h2>Login</h2>
<form action="/login" method="POST">
<div>
<label for="username">Username:</label>
<input type="text" id="username" name="username" required>
</div>
<div>
<label for="password">Password:</label>
<input type="password" id="password" name="password" required>
</div>
<div>
<button type="submit">Login</button>
</div>
</form>
</div>
</body>
</html>"""
app.run()
这只是一个示例代码,没有写的东西可以改变,比如
username
,password
和secret.key
。
如果您还有任何疑问,请发表评论。
这里有一些文档可以帮助您进一步完成项目。 :)