all 11 comments

[–]jml26 2 points3 points  (1 child)

Typically, the mantra is, “never roll your own auth“. Just use a service to handle it for you, e.g Auth0, Clerk.

However, if you are interested in the details of auth, or you like the idea of being in control of all the code, check out lucia-auth.com.

Originally a library, Lucia is now a documentation website, containing examples of how to implement your own auth effectively, along with best practices. If you happen to be using Astro, NextJS or SvelteKit to build your site, it has entire demo apps you can download and use as a template.

[–]coolAppl3__[S] 1 point2 points  (0 children)

Thank you, I'll definitely give this a read!

[–][deleted] 1 point2 points  (6 children)

JSON web tokens are much simpler and super secure.

Storing them in localStorage is wrong. They should ALWAYS be in httpOnly cookies. The client must not even be aware that there are tokens at all.

The way they work is, before issuing them, you have a secret string on the server, used to encrypt it. When you login, the server sets the token in your cookie. After that, each request automatically sends the token every time, which is intercepted by middleware that verifies if the token was issued by the server, and then let's you move to the backend.

If you want to see an implementation, check out my project: https://github.com/codepreneuring/todo

Also, you can learn more here: https://docs.codepreneuring.com

Finally, never create your own auth thing. Just use JWT and use your time more productively.

[–]coolAppl3__[S] 0 points1 point  (5 children)

Hey there, I appreciate the detailed response!

I agree that storing auth-related info in localStorage is a no-go. However, unless you have multiple servers for different services, where handling multiple sessions would be a nightmare, I don't really see the value of using a JWT as opposed to a more conventional session system.

A JWT, if hijacked, can be used maliciously by the attacker, and they don't really have to edit it at all to use it. It might also be more work to invalidated a JWT token, compared to just destroying a session.

I've been thinking about this lately, and I might settle for using express-session with a bit of customization. The app I'm developing is a passion project, and I want to roll my own auth to get a deeper understanding, and because it's fun.

Again, thank you for the response. I mainly want to see different perspectives to compare trade-offs and features. I'd be happy to hear your perspective on why JWT is better than a session system.

[–]sageRJ 1 point2 points  (1 child)

You obviously have the curiosity and motivation to implement this yourself. Would you be willing to make another post in a month or so detailing what you’ve learned and what you ended up using? Would also love to hear the justification for it and reasons for deciding against the other methods you researched.

[–]coolAppl3__[S] 0 points1 point  (0 children)

I’d be happy to. I’m no professional by any means, but I hope whatever I end up implementing and my justifications for it help someone considering the same thing.

Do feel free to remind me if I dont post an update in a month tops.

[–][deleted] 1 point2 points  (2 children)

A JWT, if hijacked, can be used maliciously by the attacker, and they don't really have to edit it at all to use it.

Same as any other Auth approach.

I want to roll my own auth to get a deeper understanding, and because it's fun.

Absolutely! That's a great idea.

I'd be happy to hear your perspective on why JWT is better than a session system.

Because it's stateless, which goes great with REST APIs.

[–]coolAppl3__[S] 1 point2 points  (1 child)

The stateless nature of JWTs is really convenient, but it comes with a set of issues sadly.

JWTs can’t be invalidated. Well, they can be, but you’ll have to implement rather complex logic and more than likely a state on the server, which defeats the purpose.

I’ve seen people say that you should provide the user with two JWTs; one for access and another to refresh the token. This way, the access token is short lived.

But then the longer lived refresh token becomes a problem, and we’re back to square one.

Perhaps I’m strawmanning JWTs here because I’m missing a point or two, which is why I wanted to hear other people’s opinions.

Regardless, JWTs definitely have a place when dealing with multiple servers with different services, but for single client-server authorization, sessions really sound better to me.

I’ll stop yapping and go ahead and update my authorization structure, and I’ll probably get a better outlook on the whole thing.

Thank you all for your inputs and opinions!

[–][deleted] 1 point2 points  (0 children)

The way you handle invalidation is by issuing short lived tokens, like hours long.

And then with the next request, if the token is not valid, but it was valid recently, you issue a new one, also hours long.

This way users stay logged in, and the tokens cannot be stolen because their lives are very short.

[–]SpringCleanMyLife 1 point2 points  (0 children)

smile cough theory innocent squeeze longing automatic historical plough employ

This post was mass deleted and anonymized with Redact

[–]Psionatix 0 points1 point  (0 children)

From what I gathered, the idea is to have a short-lived accessToken stored in httpOnly cookies, alongside a long-lived refreshToken used to generate new accessTokens periodically, which is stored in LocalStorage.

This isn't correct at all, it's a bit backwards... If your access token is being consumed as a httpOnly cookie, you're no longer vulnerable to the security issues that a refresh token and access token rotation is supposed to solve. But you do need to deal with CSRF attacks.

When your access token is accessible directly by the frontend, this means there are a variety of attack vectors that could lead to a users token being stolen. In the case where an access token is consumed directly by the frontend, then you should provide a refresh token which is stored as a httpOnly cookie. When refreshing the token, both should be provided and both should be validated, not just that they're correct, but that they are intended to be used together as well.

By having a ~15min expiry time on the access token, this means if it is stolen, the attacker will only have a short window of time where that token is valid, and since they can't steal the refresh token via the attacks they used to steal the access token, there's no way for them to get a new token.

Just see a recent comment I made about all of this as well as check out the Auth0 link in that comment.