Как обрабатывать вход пользователя в систему с помощью фляги в Python?Python

Программы на Python
Ответить
Anonymous
 Как обрабатывать вход пользователя в систему с помощью фляги в Python?

Сообщение Anonymous »

Я разрабатываю базовое веб-приложение с помощью Python flask и пытаюсь изменить некоторые из используемых мной шаблонов в зависимости от того, вошел ли пользователь в систему. Я использую mongoDB для хранения пользовательских данных.
Ниже приведено содержимое моего скрипта авторизации, содержащее определение модели пользователя, методы регистрации и входа, а также вспомогательный метод check_login:
auth_blueprint = Blueprint('auth', __name__, template_folder='templates')

# Setup Flask-Login and Bcrypt
bcrypt = Bcrypt()
login_manager = LoginManager()
login_manager.login_view = "auth.login"

# MongoDB configuration
mongo_uri = config.mongo_uri
client = MongoClient(mongo_uri)
db = client[config.DB_NAME]
users_collection = db["users"]

# User class for Flask-Login
class User(UserMixin):
def __init__(self, id, username, password):
self.id = id
self.username = username
self.password = password

@staticmethod
def get(user_id):
user_data = users_collection.find_one({"_id": user_id})

if user_data:
return User(str(user_data["_id"]), user_data["username"], user_data["password"])
return None

def get_id(self):
return self.id

@login_manager.user_loader
def load_user(user_id):
print(f'load_user method is called and the user_id is {user_id}')

try:
return User.get(user_id)
except:
return None

@auth_blueprint.route("/register", methods=["GET", "POST"])
def register():
if request.method == "POST":
username = request.form["username"]
password = request.form["password"]
confirmed_password = request.form["repeat-password"]

if not username:
flash("Please enter a username.", "danger")
return redirect(url_for("auth.register"))

if users_collection.find_one({"username": username}):
flash("Username already exists!", "danger")
return redirect(url_for("auth.register"))

if not password:
flash("Please enter a password.", "danger")
return redirect(url_for("auth.register"))

if not confirmed_password:
flash("Please confirm the password.", "danger")
return redirect(url_for("auth.register"))

if password != confirmed_password:
flash("Passwords must match!", "danger")
return redirect(url_for("auth.register"))

hashed_password = bcrypt.generate_password_hash(password).decode("utf-8")
users_collection.insert_one({"username": username, "password": hashed_password})
flash("Registration successful!", "success")
return redirect(url_for("auth.login"))

return render_template("register.html")

@auth_blueprint.route("/login", methods=["GET", "POST"])
def login():
if request.method == "POST":
username = request.form["username"]
password = request.form["password"]

# Check if the user exists and credentials are valid
user_data = users_collection.find_one({"username": username})
print(user_data)
if user_data and bcrypt.check_password_hash(user_data["password"], password):
session.clear()
user = User(str(user_data['_id']), user_data['username'], user_data['password'])
print(f'User id is {user.id}')
result = login_user(user, remember=True, duration=timedelta(days=7), force=True)
session.modified = True
print(f'Is user authenticated in login function: {current_user._get_current_object().is_authenticated}')
# print(f'Current user type is {type(current_user.is_authenticated)}')
if result:
print("Loggin successful!")
#print(f"Session after login: {session}") # Inspect session object
flash("Login successful!", "success")
return redirect(url_for("index"))
else:
print("Something went wrong :(")

return redirect(url_for("auth.login"))
# session['username'] = user.username

# if not helpers.url_has_allowed_host_and_scheme(next, request.host):
# return abort(400)

else:
flash("Invalid credentials!", "danger")

return render_template("login.html")

@auth_blueprint.route("/check_login")
def check_login():
print(f'Is user authenticated in check_login function: {current_user._get_current_object().is_authenticated}')
print(type(current_user._get_current_object()))
if current_user._get_current_object().is_authenticated:
return f"User {current_user.name} is logged in."
else:
return "No user is logged in."


P.S. Часть HTML, которая должна меняться в зависимости от входа пользователя в систему, также зависит от атрибута current_user._get_current_object().is_authenticated , поэтому я опустил ее, поскольку она показалась избыточной. Я также хотел бы отметить, что метод _get_current_object() прокси current_user ничего не меняет, и я использую его как взаимозаменяемый в целях тестирования.
Я просмотрел другие подобные вопросы и официальную документацию, но безуспешно. Мне кажется, что проблема сводится к тому, что прокси current_user не запоминается правильно, когда я перенаправляю его из функции входа; отладка во время функции входа в систему показывает, что для параметра current_user установлен экземпляр моего класса User , а для атрибута is_authenticated установлено значение True, но один раз Я перенаправляю в функцию check_login() прокси-сервер current_user по умолчанию на объект типа AnonymousUserMixin. Я подозреваю, что что-то не так с обработкой свойств сеанса , но я не могу этого понять.
EDIT:
Проблема была в функции load_user, я пытался получить идентификатор объекта без конвертации в формат BSON, который использует MongoDB. Исправленный метод показан ниже. Если оставить этот вопрос, это может помочь кому-то решить аналогичную тривиальную проблему.
@login_manager.user_loader
def load_user(user_id):
user_data = users_collection.find_one({"_id": ObjectId(user_id)})
if user_data:
return User(str(user_data['_id']), user_data['username'], user_data['password'])
return None


Подробнее здесь: https://stackoverflow.com/questions/793 ... -in-python
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»