Почему я получаю сообщение об ошибке Key при вызове сеанса 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"])

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

Ваша помощь будет очень признательна здесь, большое спасибо заранее.

ОБНОВИТЬ:

Вот где я установил сеанс [email]:

@app.route(/email_confirmation, методы=[GET, POST])
определение подтверждения():

    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=("[email protected]"),
                 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)

person CHL    schedule 15.09.2020    source источник


Ответы (1)


Ошибка сообщает вам, что в объекте сеанса нет значения электронной почты.

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

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

person jurez    schedule 15.09.2020
comment
Извините, забыл добавить этот кусок кода. Только что обновил свой исходный вопрос с помощью этого кода. Большое спасибо за ваш ответ кстати - person CHL; 15.09.2020
comment
Я предполагаю, что ваше представление подтверждения электронной почты должно быть позже в процессе регистрации, чем представление авторизации/регистрации, или что оно не запускалось в сеансе, в котором вы получаете сообщение об ошибке. - person Glenn; 16.09.2020