Почему я получаю ошибку ключа при вызове сеанса flask?

#python #session #flask #keyerror

#python #сеанс #flask #ошибка ключа

Вопрос:

У меня проблема с пользователями, пытающимися зарегистрироваться в моем приложении (которое представляет собой приложение Flask, развернутое на Pythonanywhere с MongoDB Atlas).

В основном, когда они регистрируются, они получают электронное письмо с токеном, на который им нужно нажать для подтверждения. Когда они нажимают на эту ссылку, они должны войти в приложение, но вместо этого они получают ошибку.

Когда я проверяю журнал ошибок, это то, что я вижу (в разделе «/ auth / register») при вызове:

 existing_user = User.get_by_email(session["email"])

return super(SecureCookieSession, self).__getitem__(key)
  

Было выдано исключение KeyError: 'email' .

Кажется, что как-то session["email"] не работает?

Это мой код:

 @app.route('/confirm/<token>')
def confirm_email(token):
    try:
        email = ts.loads(token, salt="email-confirm-key", max_age=7200)

    except:
        return render_template("token_expired.html")

    user = Database.find_one(collection="users", query={"email": email})

    return redirect(url_for("register_user"))


@app.route("/auth/register", methods=["GET", "POST"])  
def register_user():

    existing_user = User.get_by_email(session["email"])

    if existing_user is None:

        email = session["email"].lower()  # our website is making a request to our app
        username = session["username"]
        companyname = session["companyname"].lower()
        password = session["password"].encode("utf-8")

        hashed_password = bcrypt.hashpw(password, bcrypt.gensalt())

        User.register(email, username, companyname, hashed_password)   
       
        session["companyname"] = companyname       

        excisting_company = Database.find_one(collection="companies", query={"email": session["email"]})

        if excisting_company is None:

            new_company = NewCompany(session["companyname"], session["email"])
            new_company.company_save_to_mongo()

        else:
            return "A company has already been registered under your email address"

    else:
        return render_template("email_already_exists.html")

    return redirect(url_for("user_results"))


@classmethod
    def get_by_email(cls, email):
        find_email = Database.find_one(collection="users", query={"email": email})
        if find_email is not None:
            return cls(email=find_email["email"], username=find_email["username"],
                       companyname=find_email["companyname"], hashed_password=find_email["password"],
                       date=find_email["date"], _id=find_email["_id"])
  

Кажется, я не могу понять, почему, поскольку, когда я регистрируюсь, это работает просто отлично.

Ваша помощь была бы высоко оценена здесь, заранее большое спасибо.

Обновить:

Здесь я устанавливаю сеанс [«электронная почта»]:

@app.route(«/email_confirmation», методы=[«ПОЛУЧИТЬ», «ОПУБЛИКОВАТЬ»])
подтверждение def():

     email = request.form["email"].lower() 
    companyname = request.form["companyname"].lower()
    password = request.form["password"]
    username = request.form["username"]
    session["password"] = password
    session["email"] = email
    session["companyname"] = companyname
    session["username"] = username

    existing_user = User.get_by_email(email)

    if existing_user is None:

        msg = Message("Confirm your email", sender=("hello@weliketalent.com"),
                 recipients=[email])

        token = ts.dumps(email, salt="email-confirm-key")

        confirm_url = url_for("confirm_email", token=token, _external=True)

        msg.html = render_template("email/activate.html", confirm_url=confirm_url)

        mail.send(msg)
  

Ответ №1:

Ошибка сообщает вам, что в объекте сеанса нет значения «email».

Я не вижу, чтобы вы устанавливали это значение где-либо в своем коде. Как он должен туда попасть? Кто-то должен установить это где-то перед запуском этого кода.

В дополнение к этому, вы должны спроектировать свой код так, чтобы он не зависал в таких случаях, поскольку это может быть уязвимостью в системе безопасности. Вы можете использовать if "email" not in session для тестирования.

Комментарии:

1. Извините, забыл добавить этот фрагмент кода. Только что обновил мой первоначальный вопрос этим кодом. Большое спасибо за ваш ответ, кстати

2. Я предполагаю, что ваш просмотр подтверждения по электронной почте должен быть позже в процессе регистрации, чем просмотр авторизации / регистрации, или что он не был запущен в сеансе, где вы получаете ошибку.