I'm writing an app-server and there is an option to just use secure cookies for authentication. Here's how it seems to work:
- You define a 32-byte secret key on the server
- When the user logs in, you check the database to see if the bcrypt hashes match, and if so, you call
request.remember(user_id)
- On route handlers that require authentication (and the user_id), you unwrap the user_id by decrypting the cookie and if it's valid, you continue. Otherwise, return an
Unauthorized
error. - If a user hits the logout handler I just call
request.forget()
and the cookie is deleted on the client.
This all seems to work. So what I'm curious about is why doesn't everyone just do this? I look around and there seems to be a lot of talk of JWTs, generating auth token UUIDs and storing them in Redis/the database, etc. So apparently this method isn't secure? And you need to store state on the server?
If I were to guess, I'd say a problem with this approach might be that if the cookie is stolen somehow (not sure how since it's all over TLS and the cookies are HTTP-Only and Secure if that matters), then the user would be able to be impersonated by an attacker. But I think this would apply to the other schemes too?
Another issue I could see is that a user could just randomly generate auth tokens until they found one that matched a user? But I'm not sure if this is a problem either since I'd just rate limit the authentication handler and I'd imagine this sort of thing would take a while? Oh, maybe they could make 100 accounts and see what the encrypted cookie auth token looked like and bruteforce it client-side to find out what the secret key on the server was? And then they'd be able to impersonate users by generating auth tokens? Although I think it would take way too long to find the key since it's 32 bytes?
I guess this approach doesn't automatically expire cookies (is that why this isn't used much? But I think there's a way to add an expiry header to cookies? Would that work?) I'm not even sure if I need expiration for this app.. Seems like it would annoy users. How long do sessions last at places like Google/Facebook? I feel like I'm always logged into those services forever.
I don't know. I feel like I'm missing a lot of information here. Is there somewhere where I can find a pros and cons list of all these different approaches?
request.remember
andrequest.forget
do here? And what do you use the 32 byte secret key for? You mention decrypting a cookie, but not encrypting or setting any cookies.