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:
- Anyone can add animals!
- 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?
C is for Cookie!
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.