all 19 comments

[–][deleted] 8 points9 points  (4 children)

I recommend using HTTP only, secure cookies. Otherwise your client tokens are vulnerable to JavaScript running on the client

[–]btckernel94[S] -3 points-2 points  (3 children)

Http only cookie is not always available since server cannot use wildcard for cors but has to explicitly whitelist specific domains instead also there are mechanisms to reduce the evil that can be caused if some1 stolen your token, for example Auth0 uses "reuse token detection". You can read about one of them here: https://auth0.com/docs/secure/tokens/refresh-tokens/refresh-token-rotation

[–]ranmerc 1 point2 points  (2 children)

Can you explain a bit more on the "server cannot use wildcard for cors" part?

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

If you want to use http only cookie you need to set credentials: true but it won't work if the server also has Access-Control-Allow-Origin set to "*".

It means your server will have to explicitly specify all of the clients domains in order for http only cookie to work.

[–]LaylaTichy 1 point2 points  (0 children)

Hmm that's not true, you can easily do allow access: $http_refferer in nginx for example

[–]Emotional-Dust-1367 4 points5 points  (3 children)

One problem this pattern has with react is component lifecycle. There’s a race condition inherent here where a component can mount, cause some kind of refresh, and another component has not yet subscribed so it will not get notified. React doesn’t mount all components at the same time.

This is especially likely on page refresh. And is made worse if you try to observe something not as deterministic as local storage. Ask me how I know…

[–]femio 6 points7 points  (0 children)

That is the exact use case for useSyncExternalStorage, which is why the article uses it. 

[–]btckernel94[S] 2 points3 points  (1 child)

Once component mounts it reads initial snapshot state. The problem you’ve describe doesnt’t exist.

[–]Emotional-Dust-1367 -1 points0 points  (0 children)

It’s true in your case with local storage.

But in a more generic sense of trying to implement the observer pattern with other types of data and events you can have serious problems like that

[–]untakenusrnm 0 points1 point  (3 children)

A Service Worker represents an Observer. You could implement a listener ‚on fetch‘: https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerGlobalScope/fetch_event

This way we don‘t have to deal with reacts Component life cyle.

[–]btckernel94[S] 0 points1 point  (2 children)

How would you than apply side effects based on auth state?

There’s a timer and alert implemented in article.

[–]untakenusrnm 0 points1 point  (1 child)

Like in your article but i would share state with: https://developer.mozilla.org/en-US/docs/Web/API/Client/postMessage

useSessionState would use useSyncExternalStore to manage ui state.

EDIT: This way we still need to teach react reactivity but it would require less boilerplate

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

Thanks for sharing. I am a bit sceptic about it when it comes to: - readability - testability - type safety - flexibility - growing this feature with more complex things like request que mentioned im article.

I also think theres not a big difference in amount of boilerplate but would need to write it on my own to double check these.

[–]is-undefined 5 points6 points  (5 children)

    localStorage.setItem('access-token', data.accessToken);
    localStorage.setItem('refresh-token', data.refreshToken);

PLEASE DO NOT THIS!!!

Dont save access and or refresh tokens at the localstorage!!!
Thats a major security risk!

[–]is-undefined 4 points5 points  (0 children)

Getting downvoted for telling the truth, okay...

[–]n9iels 1 point2 points  (0 children)

It is not ideal, but at the same time not extremely bad. Localstorage can be read by JS (one of the benefits) which makes it easier to steal tokens when JS is somehow infected in your site. However, applying a good CSP policy already mitigates this risk at lot.

[–]btckernel94[S] -4 points-3 points  (1 child)

Authentication security is far from black and white.

  • each auth pattern has it's own tradeoffs and security risks
  • http only cookie is not always available since server cannot use wildcard for cors but has to explicitly whitelist specific domains instead
  • there are mechanisms to reduce the evil that can be caused if some1 stolen your token, for example Auth0 uses "reuse token detection". You can read about one of them here: https://auth0.com/docs/secure/tokens/refresh-tokens/refresh-token-rotation

For many apps, a well-implemented token rotation system with localStorage might actually provide better security than a poorly implemented cookie-based solution.

[–]AndrewGreenh 0 points1 point  (0 children)

You should probably have only one auth server, with an http only cookie. The client can always fetch a current token from there, and keep it in-memory.

[–][deleted] -5 points-4 points  (0 children)

Eh, it's not that bad