Jyan Z
Jyan Z

Reputation: 26

value error if cookie value is a string but not if an int

In my make_session function, if the passwords from the forms don't match some credentials, then it returns a string which ends up being stored as a cookie named session. In my index file, I have it set so on index.html, if the cookie value is {}, it asks for login information. If I change what is returned from the make_session function by replacing "invalid" with any integer, the code works as expected.

A bad solution to my problem is to add

except:
    data = {}

before the return to my get_saved_data function setting data equal to {} but this ends up with the same results as if I had no cookie in my browser at all, but it gets rid of my error which is here: https://gist.github.com/anonymous/e101aa46f154a075b038

I suspect that the get_saved_data function may be a fault.

Map of my directory:

                         |---- layout.html
                         |---- index.html
         |--- templates -|
Project -|
         |--- test.py

test.py:

from flask import Flask, render_template, redirect, url_for, request, make_response
import json

def get_saved_data(key):
    try:
        data = json.loads(request.cookies.get(key))
    except TypeError:
        data = {}
    return data


def make_session(form_data):
    if form_data.get('username') == "username" and form_data.get('password') == "password":
        return "12345"
    else:
        return "invalid"


app = Flask(__name__)


@app.route('/')
def index():
    data = get_saved_data("session")
    return render_template('index.html', saves=data)


@app.route('/login', methods=['POST'])
def login():
    response = make_response(redirect(url_for('index')))
    response.set_cookie("session", make_session(dict(request.form.items())))
    return response

app.run(debug=True, host='0.0.0.0', port=8000)

index.html:

{% extends "layout.html" %}

{% block content %}
    {% if saves == {}: %}
        <p>Please log in.</p>
    {% else: %}
        <p>Your Session value is: {{ saves }}</p>
    {% endif %}
    {% if saves == {}: %}
        <form action="{{ url_for('login') }}" method="POST">
            <p>We take your private information very seriously. All data is encrypted not once but twice! in ROT13 to provide the best security.</p><br />
            <label for="username">Please enter your username:</label>
            <input type="text" name="username" /><br />
            <label for="password">Please enter your password:</label>
            <input type="text" name="password" /><br />
            <button class="btn">Log In</button>
        </form>
    {% endif %}
{% endblock %}

layout.html:

<!DOCTYPE html>
<html>
    <head>
        <title>Character Generator</title>
    </head>
    <body>
        {% block content %}{% endblock %}
    </body>
</html>

Upvotes: 1

Views: 642

Answers (2)

Jyan Z
Jyan Z

Reputation: 26

While I haven't found a way to directly fix the issue, and using lord63.j's answer saved me a few lines of code, a way to indirectly fix the issue is to save the cookie value as a dictionary by modifying the login function to this:

@app.route('/login', methods=['POST'])
def login():
    response = make_response(redirect(url_for('index')))
    response.set_cookie("data", json.dumps({"session": make_session(dict(request.form.items()))}))
    return response

from them on, in order to access the session value I'll need to use

saves.get('session')

as saves is equivalent to

json.loads(request.cookies.get('data', '{}'))

in the index function

@app.route('/')
def index():
    data = get_saved_data("data")
    return render_template('index.html', saves=data)

Upvotes: 0

lord63. j
lord63. j

Reputation: 4670

Change your get_saved_data to the following will make any difference?

def get_saved_data(key):
    data = json.loads(request.cookies.get(key, '{}'))
    return data

return '{}' if there is no such key, make sure json won't complain anything.

Upvotes: 1

Related Questions