Ep.15 Flask cookies

Flask cookies | Learning Flask Ep. 15

Setting, getting and working with cookies in Flask

Cookies play an important role in most modern websites and web applications, allowing us leave small strings of key/value pairs on the clients browser to help both developers and users by temporarily preserving inportant information such as preferences, unique identifiers, state etc..

Fortunately for us, Flask makes working with cookies very simple.

Let’s get started.

Flask imports

Working with cookies requires a couple of imports from Flask.

  • request To set and get cookies
  • make_response - To build a response to attach cookies to

Go ahead and import them at the top of your Flask app:

from flask import request, make_response

Create a new route

For this example, we’re going to create a simple route with the URL /cookies:

@app.route("/cookies")
def cookies():

    resp = make_response("Cookies")

    return resp

We’ve create a response by passing a simple string to the make_response function resp = make_response("Cookies") which is then returned.

The exact same thing would be achieved with:

@app.route("/cookies")
def cookies():

    return "Cookies"

We’re not covering make_response in detail in this part, just know that you can build your response ahead of time and modify it before returning it!

If you wanted to return a template, you would do the following:

@app.route("/cookies")
def cookies():

    resp = make_response(render_template("cookies.html"))

    return resp 

It’s exactly the same as:

@app.route("/cookies")
def cookies():

    return render_template("cookies.html") 

The difference is that by using make_response we can build and modify our request ahead of sending it.

Setting cookies

Setting cookies is a simple affair. We simply attach them to our response object.

The syntax for setting a cookie is:

response.set_cookie("key", "value")

For example, let’s set a cookie with the key of flavor and the value of chocolate chip:

@app.route("/cookies")
def cookies():

    resp = make_response("Cookies")

    resp.set_cookie("flavor", "chocolate chip")

    return resp

If you open the developer tools in your browser, head to the storage tab and select cookies from the navigation on the left, you’ll see that the flavour cookie has been set!

You might notice in the developer tools, cookies have several parameters including key, value, domain, path and more, all of which can be set using Flask.

The set_cookie function takes the following parameters:

set_cookie(
    key, 
    value='', 
    max_age=None, 
    expires=None, 
    path='/', 
    domain=None, 
    secure=False, 
    httponly=False, 
    samesite=None
)

See the table below for a breakdown of the cookie parameters available:

Parameter Default Description
key required The key (name) of the cookie
value ”” The value of the cookie
max_age None Number of seconds or None (default)
expires None The date of then the cookie expires, must be a datetime object
path None Limits the cookie to a given path
domain None specify a domain able to read the cookie (default is the domain that set it)
secure False If True, the cookie will only be available over HTTPS
httponly False Disallow JavaScript to access the cookie (Limited browser support)
samesite False Limits the scope of where the cookie is accessible to the same site

These options give us a great deal of control of how our cookies work and provide plenty of ways to manage them.

Let’s set the max_age and path keys with 30 seconds and the /cookies path:

resp.set_cookie(
    "flavor", 
    value="chocolate chip",
    max_age=10,
    path=request.path
)

We’ve used request.path to access the path of the current route

If you check your browsers developer tools console, you’ll see our flavor cookie now has an Expires on date along with a value for Path of /cookies.

We’re going to come back to max_age in a minute with another example, but now let’s talk through how to access cookies.

Accessing cookies

Just like we’ve used the request object to access many different request values including request.form, request.args, request.files and request.get_json()..

We use request.cookies to access the cookies with the following syntax:

cookies = request.cookies

If you run print(request.cookies) you’ll see we get a nicely serialized Python disctionary:

print(request.cookies)
{'flavor': 'chocolate chip'}

As we’re now working with a dictionary, we can access the individual values by key:

flavor = cookies.get("flavor")

Tip - Use cookies.get("key") to access keys in order to mute any key errors when trying to access the dictionary values by key

Let’s set a few more cookies:

resp.set_cookie("chocolate type", "dark")
resp.set_cookie("chewy", "yes")

If we now print request.cookies, we see:

{'flavor': 'chocolate chip', 'chocolate type': 'dark', 'chewy': 'yes'}

max age

You may notice that even after setting max_age in our flavor cookie, it still hangs around in the developer tools.

Go ahead and comment out the first cookie we set:

@app.route("/cookies")
def cookies():
    resp = make_response("Set cookies")
    cookies = request.cookies
    print(cookies)

    # resp.set_cookie(
    #     "flavor", 
    #     value="chocolate chip",
    #     max_age=10,
    #     path=request.path
    # )

    resp.set_cookie("chocolate type", "dark")
    resp.set_cookie("chewy", "yes")

    return resp

Refresh the page and give it 10 seconds or so. You’ll notice we get the following in the terminal output:

{'chocolate type': 'dark', 'chewy': 'yes'}

Even though the flavor cookie persists in the browser, it’s not send to the server as we explicitly set the max_age variable in the cookie to 10 seconds. It will be deleted when the browser is closed.

Tip - To delete cookies from your browser, right click on the domain in the cookies tab in the developer tools and click on delete

Setting cookies from the client

Setting cookies using JavaScript is also very simple.

document.cookie = "key=value";

This will set the most basic type of cookie with no other meta information.

We can also provide the cookie with some more parameters like so:

document.cookie = "key=value; expires=DDD, DD MMM YYYY HH:MM:SS UTC";

You can also add a path with the following:

document.cookie = "key=value; expires=DDD, DD MMM YYYY HH:MM:SS UTC; path=/path";

You’ll then be able to access any of the cookies set client-side using

request.cookies

Sessions

Sessions use a special type of signed cookie, but you’ll have to read the next episode in this series to learn more!

Last modified · 28 Feb 2019

Written with StackEdit.