HTTP & Cookies
HTTP
Two most important parts of a request:
-
How // HTTP method (verb - e.g.
GET
,POST
) -
What // Path (e.g.
/contact
or/contact?lang=fr
)- key value pair
Statelessness
HTTP does not remember you between requests - think Dory from Finding Nemo
In order to prompt the server to remember us, we need an identifier - think membership card at GoodLife. They have all of our user info in their system, but they give us a membership card to prompt their system into identifying us quickly.
Remembering state without cookies
How do we do this?
Example:
- User sends
GET
request to/profile
- Server has no clue who you are
- Server sends redirect (
302
) to/login
to client - Browser/user makes
GET
request to/login
- Server renders
login
view (hypotheticallylogin.ejs
) - User fills out login form with valid credentials and clicks submit
- Browser/user makes
POST
request to/login
with form data as 'payload' - Server validates payload and finds the correct user object
- Server redirects to
/profile
- User navigates to
/
, sending aGET
request - Server has no idea who user is. Go back to step 3, lather, rinse, repeat.
Alternate approach
- Steps 1-9 above
- User navigates to
/?username=mlaws
, sending aGET
request - Server looks up user based on
username
param - Server finds correct user object and responds with
profile.ejs
, and we make sure to interpolate?username=mlaws
to every link in our app (what a pain)
<% if (currentUser) { %>
<a href="/?username=<%= currentUser.username %>">HOME</a>
<% } else { %>
<a href="/login">LOGIN</a>
<% } %>
Problems with this approach:
- Security:
- Very easy to brute force quess usernames and impersonate someone
- Sharing URLs means sharing your logged in state
- Usability:
- Closing tab/window will log me out (unless I go back to URL with query string)
Enter: Cookies!
Instead of exposing data in query params in the URL, we can store data in a cookie.
The cookie is assumed to be stored by the client, who will send it with EVERY request.
This addresses most of the problems outlined above (with one glaring exception).
Demo 1: Language Switcher
--- BREAK
Demo 2: User Authenication
Security
Problems with our demo:
- Devs/Ops have access to people's passwords (this happened on GSuite recently!) === BAD
- Hash passwords
password: '123'
becomes:_sesson="aa104e-f8b4d64a8-d8177e84-6509439d0"
in an MD5 hash, for example- Don't do this yourself, you aren't a cryptographer
- Hash passwords
- Cookie is not encrypted, which opens us up to
ManPerson in the Middle attacks (MITM) for all of our requests!- We need HTTPS in order to fully encrypt our requests
cookie-session
node module encrypts and signs our cookies by default! Yay!