CHL
CHL

Reputation: 31

Why do I get a Key error when calling flask session?

I have a problem with users trying to register on my application (which is a Flask app deployed on Pythonanywhere with MongoDB Atlas).

Basically when they register they receive an email with a token that they need to click on to confirm. When they click on that link they should enter the application, but instead they receive an error.

When I check the error log, this is what I see (under "/auth/register") when it calls:

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

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

Exception KeyError: 'email' was thrown out.

It seems that somehow the session["email"] does not work?

This is my code:

@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"])

I cant seem to figure out why, as when I register myself it works just fine.

Your help would be greatly appreciated here, many thanks in advance.

UPDATE:

Here is where I set the session["email"]:

@app.route("/email_confirmation", methods=["GET", "POST"])
def confirmation():

    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)

Upvotes: 3

Views: 3437

Answers (1)

jurez
jurez

Reputation: 4657

The error is telling you that there is no "email" value in session object.

I don't see you setting this value anywhere in your code. How is it supposed to get there? Somebody needs to set it somewhere before this code runs.

In addition to that, you should design your code not to crash in such cases, as this could be a security vulnerability. You can use if "email" not in session for test.

Upvotes: 2

Related Questions