How to handle the InvalidCSRFTokenError which is caused by logout twice?

I’m making SessionController on Phoenix.
I have a invalid CSRF token problem which is caused by logout twice.

The situation is below,

Step 1. Open browser, access the site and then login.
Step 2. Open new tab, access the same site and then logout.
Step 3. Switch to Step 1 tab and logout again. (for double logout test )

On Step3, I get InvalidCSRFTokenError.

Could you teach me a standard way to handle this on Phoenix?

ref) https://stackoverflow.com/questions/45361702/in-laravel-when-run-logout-route-twice-consecutively-i-get-csrf-token-mismatch

Is this a real issue you have? This seems like a “nice to have” feature but sure, I can tell how how to do it.

When logging out, send a channel event to all open tabs for that user and make them refresh the pages. Then every tab should be redirected to login.

This requires that you set up a channel for a current user and than have that action defined in JS

2 Likes

The simplest solution is probably to not rely on a form to log out, but use a regular GET request instead. This won’t be correct from the view of REST semantics but should work.

2 Likes

One problem with using GET (or other means of skipping CSRF protection) would be that someone could trick users to click on a link on another website and, as a result, logout from your app.

You need to assess how much of a danger that would pose: if the impact and risk are low, what @NobbZ suggested is probably easier. Otherwise, broadcasting a reload message to other tabs/windows like @andreaseriksson explained is a safer approach.

2 Likes

Another way to do what @andreaseriksson explained, but without relying on server side code like channels, would be to use the localStorage or BroadcastChannel JavaScript APIs as a broadcast mechanism. For example, this blog post discusses a few ways: https://blog.arnellebalane.com/sending-data-across-different-browser-tabs-6225daac93ec

The basic idea would still be the same: the tab where the user logs out would broadcast a message to other open tabs, causing them to reload.

If the website is running a service worker, I would extend its functionality to messaging other tabs (and redirecting them to the login page), as described in this guide.

Thanks for your reply, @andreaseriksson, @NobbZ, @lucaong and @konstantine.

I understand the 2 ways, use GET or use channel for notifying to client. Thank you.

And I investigated other popular site github and gitlab, how to handle this.
They just return 422 status.

I just didn’t know the standard way of web application.
So now I came to think @andreaseriksson’s comment “This seems like a “nice to have” feature” is right.

Plug returns 403 status to client for InvalidCSRFTokenError.
I decided to use this.

Thank you.

1 Like