KeyError: 'user' when I use sessions with templates (jinja) – Python Flask

Issue

I’m trying to make a simple template navbar that tells non-logged in users to login or signup, and tells logged in users to log out, but I am getting a "KeyError: ‘user’" error when I do so. I have no idea why this is happening since this worked for me before.

If someone could help guide me, that would be greatly appreciated!

Template

                {% if session['logged_in'] %}
                    <a href="/logout" class="w3-bar-item w3-button w3-hover-none w3-text-light-grey w3-hover-text-light-grey w3-right">Log out</a>
                    <a href="#" class="w3-bar-item w3-button w3-hover-none w3-text-light-grey w3-hover-text-light-grey w3-right">{{SESSION_USERNAME}}</a>
                {% else %}
                    <a href="#" class="w3-bar-item w3-button w3-hover-none w3-text-light-grey w3-hover-text-light-grey w3-right">Login / Signup</a>
                {% endif %}

Template Route

@app.route('/')
def index():
    return render_template('index.html', PAGE_TITLE = "Home :: ImageHub", SESSION_USERNAME=session['user'])

Login Route

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

        user = db.users.find_one({'username': username, 'password': password})

        session['user'] = user['username']
        session['logged_in'] = True;

        return redirect(url_for('index'))
    elif(request.method == "GET"):
        return render_template('login.html', PAGE_TITLE = "Login :: ImageHub")

I know the login route is super bare-bones, but right now I just want to get the login system to work.

Edit: Might I add, it works when the session[‘logged_in’] is set to true, but breaks when it’s popped.

Error

[2021-05-31 17:23:24,850] ERROR in app: Exception on / [GET]
Traceback (most recent call last):
  File "C:\Users\gabri\AppData\Local\Programs\Python\Python39\lib\site-packages\flask\app.py", line 2447, in wsgi_app
    response = self.full_dispatch_request()
  File "C:\Users\gabri\AppData\Local\Programs\Python\Python39\lib\site-packages\flask\app.py", line 1952, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "C:\Users\gabri\AppData\Local\Programs\Python\Python39\lib\site-packages\flask\app.py", line 1821, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "C:\Users\gabri\AppData\Local\Programs\Python\Python39\lib\site-packages\flask\_compat.py", line 39, in reraise
    raise value
  File "C:\Users\gabri\AppData\Local\Programs\Python\Python39\lib\site-packages\flask\app.py", line 1950, in full_dispatch_request
    rv = self.dispatch_request()
  File "C:\Users\gabri\AppData\Local\Programs\Python\Python39\lib\site-packages\flask\app.py", line 1936, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "D:\Github Repositories\Repositories\Imagehub\server.py", line 17, in index
    return render_template('index.html', PAGE_TITLE = "Home :: ImageHub", SESSION_USERNAME=session['user'])
  File "C:\Users\gabri\AppData\Local\Programs\Python\Python39\lib\site-packages\werkzeug\local.py", line 377, in <lambda>
    __getitem__ = lambda x, i: x._get_current_object()[i]
  File "C:\Users\gabri\AppData\Local\Programs\Python\Python39\lib\site-packages\flask\sessions.py", line 84, in __getitem__
    return super(SecureCookieSession, self).__getitem__(key)
KeyError: 'user'

Solution

The error KeyError: 'user' means that your session object does not contain the key user. In your EDIT section, the issue is the same, you are missing the key in your dictionary object. You need to add the user key to your session object:

def add_to_dict(dict_obj, key, value):
    # Check if key exist in dict or not
    if key in dict_obj:
        # Key exist in dict.
        # Check if type of value of key is list or not
        if not isinstance(dict_obj[key], list):
            # If type is not list then make it list
            dict_obj[key] = [dict_obj[key]]
        # Append the value in list
        dict_obj[key].append(value)
    else:
        # As key is not in dict,
        # so, add key-value pair
        dict_obj[key] = value

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

        user = db.users.find_one({'username': username, 'password': password})

        # You probably want to do some checks on user object here :)
        add_to_dict(session, 'user', user['username'])
        add_to_dict(session, 'logged_in', True)

        return redirect(url_for('index'))
    elif(request.method == "GET"):
        return render_template('login.html', PAGE_TITLE = "Login :: ImageHub")

add_to_dict is a helper function to only append the key value to the dictionary object if it does not exist in your dictionary object yet, else it will simply update the value by the key.

Answered By – Yeong Jong Lim

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published