Lecture 7.1 (March 1)

  • A2 is out
  • P3 is coming soon

Where we're at

Animals example — we added animal adding.

There are two deficiencies we want to fix:

  1. Anyone can add animals!
  2. Then a related security problem....

Goal: support user authentication.

But problem: HTTP is stateless. That is, nothing is remembered.

How do we remember that the user has logged in?

Our general pattern, remember, is that the browser drives. If we want to send the user somewhere, we send a response or a link to the browser that sends them back to the URL.

HTTP cookies allow us to ask the browser to send back some extra information with subsequent requests!

We can set a cookie by manually creating a response:

def some_handler():
    resp = flask.make_response(flask.render_template())
    resp.set_cookie('name', 'HACKEM MUCHE')
    return resp

Then any subsequent request will receive the cookie, in flask.request.cookies:

def other_handler():
    # use `get` instead of `[]` to have default value instead of KeyError
    sname = flask.request.cookies.get('name', None)
    return 'The cookie name is {}'.format(sname)

Build this in to the application.

Note

The cookie will only be sent to our server.

S is for Session

Cookies are our low-level building blocks. Using them well, however, is kinda hard.

Flask provides a higher-level abstraction called a Session that uses cookies to make it easy to remember things in a secure fashion.

But first... configuration!

settings.py

Applications need settings:

  • database authentication credentials
  • encryption keys
  • logging settings

That probably shouldn't be in git. We can split these out into a file settings.py:

SECRET_KEY = 'sadjfkla3uac90320hj3123io190rh'

And then load it:

app.from_pyfile('settings.py')

Back to sessions

Sessions use SECRET_KEY to protect sessions. Then we have another variable, flask.session, that contains information for the current user session. It is automagically set up to have the session data for the current browser session.

It acts like a dictionary!

flask.session['name'] = 'William Howard Taft'

So how can we use these?

Build login and logout forms.

Then:

flask.session['auth_user'] = authed_user

Then we can see that the user is authed!

Make the pages display useful things around this

Authorizing users

First, a bit of definition:

Authentication
Determining if the user is who they claim to be.
Authorization
Determining if the user is authorized to do what they want to do.

An authentication failure says ‘You aren't Bob!’. An authorization failure says ‘Bob, you aren't allowed to have a cookie.’

When we check the password, and then set the cookie, we are authenticating the user. The session cookies are managed such that only our server can create them, so we can trust them.

Then, when the user does something, we need to check if they're allowed to!

Even if there should be no link to let them do it.

So it is not enough to remove the Add Animal form — we must also disable the POST handler.