Python 在没有记住我选项的情况下使用Flask登录是否更安全?为什么?
我正在学习如何通过组合用户身份验证系统,使用MongoDB数据库创建Flask应用程序。当我在工作中与上司一起查看代码时,他说使用Python 在没有记住我选项的情况下使用Flask登录是否更安全?为什么?,python,flask,flask-login,werkzeug,itsdangerous,Python,Flask,Flask Login,Werkzeug,Itsdangerous,我正在学习如何通过组合用户身份验证系统,使用MongoDB数据库创建Flask应用程序。当我在工作中与上司一起查看代码时,他说使用werkzeug.security对密码进行哈希运算可能不是一个好主意,并要求我在代码中使用它的危险库(见下文) 让我发疯的是,我在网上找不到任何地方,为什么单独使用werkzeug.security是个坏主意。据我所知,这个危险的软件包允许您在使用Flask login中的memberme选项时使用登录序列化器加密和解密cookie令牌(我没有使用此选项)。我找到了
werkzeug.security
对密码进行哈希运算可能不是一个好主意,并要求我在代码中使用它的危险库(见下文)
让我发疯的是,我在网上找不到任何地方,为什么单独使用werkzeug.security是个坏主意。据我所知,这个危险的软件包允许您在使用Flask login
中的memberme选项时使用登录序列化器加密和解密cookie令牌(我没有使用此选项)。我找到了解释Flask登录
令牌
即使我不使用“记住我”选项,使用它是否仍然很重要
from flask import Flask, url_for, redirect, render_template, request
from flask_mongoengine import MongoEngine
from wtforms import form, fields, validators
from werkzeug.security import generate_password_hash, check_password_hash
import flask_login
# Create application
app = Flask(__name__)
# Create a secret key so we can use sessions
app.config['SECRET_KEY'] = 'super-secret'
# MongoDB settings
app.config['MONGODB_SETTINGS'] = {'DB': 'mymongodb'}
db = MongoEngine()
db.init_app(app)
# Create user document (MongoDB documents are like rows in a relational table).
class User(db.Document):
login = db.StringField(max_length=80, unique=True)
password = db.StringField(max_length=80)
email = db.StringField(max_length=80)
name = db.StringField(max_length=80)
# Flask-Login integration
def is_authenticated(self):
return True
def is_active(self):
return True
def is_anonymous(self):
return False
def get_id(self):
return str(self.id)
# Define login and registration forms (for flask-login)
class LoginForm(form.Form):
login = fields.StringField(validators=[validators.required()])
password = fields.PasswordField(validators=[validators.required()])
def validate_login(self, field):
user = self.get_user()
if user is None:
raise validators.ValidationError('Invalid username.')
if not check_password_hash(user.password, self.password.data):
raise validators.ValidationError('Invalid password.')
def get_user(self):
return User.objects(login=self.login.data).first()
class RegistrationForm(form.Form):
login = fields.StringField(validators=[validators.required(),validators.length(min=3, max=80)])
password = fields.PasswordField(validators=[validators.required(), validators.length(min=6, max=80)])
email = fields.StringField(validators=[validators.required(),validators.email(), validators.length(min=6, max=80)])
name = fields.StringField(validators=[validators.required(), validators.length(min=3, max=80)])
def validate_login(self, field):
if User.objects(login=self.login.data):
raise validators.ValidationError('Duplicate username.')
# Initialise flask-login
def init_login():
login_manager = flask_login.LoginManager()
login_manager.init_app(app)
# Create user loader function
@login_manager.user_loader
def load_user(user_id):
return User.objects(id=user_id).first()
# Flask views
@app.route('/', methods=('GET', 'POST'))
@app.route('/login/', methods=('GET', 'POST'))
def login_view():
form = LoginForm(request.form)
if request.method == 'POST' and form.validate():
user = form.get_user()
flask_login.login_user(user)
return render_template('main.html', user=flask_login.current_user)
return render_template('form.html', form=form)
@app.route('/register/', methods=('GET', 'POST'))
def register_view():
form = RegistrationForm(request.form)
if request.method == 'POST' and form.validate():
hashpass = generate_password_hash(form.password.data, method='sha256', salt_length=8)
user = User(form.login.data, hashpass, form.email.data, form.name.data)
user.save()
flask_login.login_user(user)
return render_template('main.html', user=flask_login.current_user)
return render_template('form.html', form=form)
@app.route('/logout/')
def logout_view():
flask_login.logout_user()
return redirect(url_for('login_view'))
@app.route('/main/')
def main_view():
if flask_login.current_user.is_authenticated:
return render_template('main.html', user=flask_login.current_user)
return redirect(url_for('login_view'))
@app.route('/map/')
def map_view():
if flask_login.current_user.is_authenticated:
return render_template('map.html', user=flask_login.current_user)
return redirect(url_for('login_view'))
if __name__ == '__main__':
# Initialise flask-login
init_login()
# Start the Flask app
app.run(debug=True)
谢谢,
Aina。生成密码\u散列
是一个用于安全散列密码的函数。它是一个用于对任意数据进行安全签名(但不是散列或加密)的库。它不适合对密码进行哈希运算
由于您正在使用Flask登录,它将为您处理cookies。在那种情况下,你不会直接使用它。Flask在幕后使用其危险性对会话cookie进行签名