585

This question is not about when to use GET or POST in general; it is about which is the recommended one for handling logging out of a web application. I have found plenty of information on the differences between GET and POST in the general sense, but I did not find a definite answer for this particular scenario.

As a pragmatist, I'm inclined to use GET, because implementing it is way simpler than POST; just drop a simple link and you're done. This seems to be case with the vast majority of websites I can think of, at least from the top of my head. Even Stack Overflow handles logging out with GET.

The thing making me hesitate is the (albeit old) argument that some web accelerators/proxies pre-cache pages by going and retrieving every link they find in the page, so the user gets a faster response when she clicks on them. I'm not sure if this still applies, but if this was the case, then in theory a user with one of these accelerators would get kicked out of the application as soon as she logs in, because her accelerator would find and retrieve the logout link even if she never clicked on it.

Everything I have read so far suggest that POST should be used for "destructive actions", whereas actions that do not alter the internal state of the application -like querying and such- should be handled with GET. Based on this, the real question here is:

Is logging out of an application considered a destructive action/does it alter the internal state of the application?

Bobby
  • 11,419
  • 5
  • 44
  • 69
Daniel Liuzzi
  • 16,807
  • 8
  • 52
  • 57
  • Well, assuming you are visiting the site for the first time, and the logout link is not present, you would be logged out when you login. It would be fine after you logged in a second time, since the logout url is already cached. But one can assume any decent accelerator would be able to filter out most logout urls. – HyperCas Aug 19 '10 at 12:10
  • 2
    HyperCas, accelerators filtering out logout URLs was a theory I was considering and one of the reasons I decided to post the question. I feel a little reluctant to just trust the accelerator logic, and one day have a user with a crappy accelerator complain that she can't login. Do you know if they follow a standard, or if such standard exists? – Daniel Liuzzi Aug 19 '10 at 12:33
  • Any Accelerator that automatically submitted a form (for example) would be malware IMO... it is totally illogical to think that an accelerator would submit a form automatically. Imagine you visit Google. How could it submit the search form? Nobody can account for Malware as it is too unpredictable and does not follow the rules. – Alex Aug 19 '10 at 12:47
  • 3
    @AlexW - I think you misunderstood my question. The accelerator scenario I proposed is to show a possible issue when using GET, not POST, so there would be no form to post, only plain links which accelerators would have no problems following. – Daniel Liuzzi Aug 19 '10 at 12:53
  • Fair enough. I would suggest then checking the User-Agent of the GET request and to verify it was the browser and not another piece of software. If not User-Agent then an equivalent property in the EventHandler object. – Alex Aug 19 '10 at 12:56
  • 2
    I realise I'm years too late for this, but Alex, that's not what Daniel is asking about. He's saying that if a user clicks a logout link and an accelerator returns the cached logout page without it hitting the application, then the user would stay logged in. Nothing to do with malware, although FYI checking a User-Agent string wouldn't fix anything anyway. – Rob Grant Aug 20 '13 at 06:03
  • Why Google accepts GET request for logging out? – Hamid Alaei Nov 05 '15 at 07:53

10 Answers10

649

Use POST.

In 2010, using GET was probably an acceptable answer. But today (in 2013), browsers will pre-fetch pages they "think" you will visit next.

Here is one of the StackOverflow developers talking about this issue on twitter:

I'd like to thank my bank for making log off a GET request, and the Chrome team for handy URL prefetching.- Nick Craver (@Nick_Craver) January 29, 2013

fun fact: StackOverflow used to handle log-out via GET, but not anymore.

David Murdoch
  • 87,823
  • 39
  • 148
  • 191
  • 3
    Thanks for this update, Dave. I didn't even notice SO switched their log out to POST, and I honestly had no clue Chrome comes with pre-fetching built in. Finally, the twit you quoted was could have never offered a better example to the problem I described in my my question and confirms my suspicions. I am up voting your answer and making it the accepted answer. – Daniel Liuzzi Feb 05 '13 at 05:16
  • 4
    In my browser, Stackoverflow logout looks like
  • log out
  • which is a GET, not a POST – boatcoder Feb 22 '13 at 14:40
  • 11
    @Mark0978, click the link. – David Murdoch Feb 22 '13 at 14:47
  • 3
    Interesting. That's probably one of my least favorite features, a logout that then asks me if I'm sure. Guess it keeps the prefetch from logging you out, but Amazon, Ebay, and Gmail all use GET for logout without that trick page in between what the user is told is logout and the actual logout event. I would imagine that in between page would lead to a lot of people mistakenly believing they were logged out. The problems with that on SO are minimal, no money involved, and 99% of everything is public anyway. – boatcoder Feb 22 '13 at 15:00
  • @DavidMurdoch Do you know how SO creates the hidden 'fkey' value that is posted along with the logout action (for security purposes)? – Ethan May 31 '13 at 21:34
  • The blame here lies on the browser part, not on the remote side. Web page can't know about what nonstandard mechanisms were built into a browser and it's silly to expect it will adopt. – Red Sep 19 '13 at 11:45
  • 2
    @Ethan I would suspect that's for CSRF prevention, and as a rule of the thumb, should accompany any POST operation. Frameworks usually provide out of the box solutions to this. e.g., Django's `csrf_token` template tag. – yati sagade Mar 30 '14 at 18:25
  • 10
    @Red According to the HTTP/1.1 standard, this is the server's fault, not the browser's. GET is expected to have no side-effects on the server side. The standard even says "the user did not request the side-effects, so therefore cannot be held accountable for them". – eyuelt Apr 14 '14 at 22:27
  • 2
    @eyuelt I'd argue that, when session is marked by setting a cookie in user's browser, removing it does not constitute server-side effect. In fact, cookies get set and removed on GET requests all the time. – Red Apr 21 '14 at 12:23
  • @Red Good point. So I guess it is the browsers' fault. But now that many browsers are doing pre-fetching, it's probably best to stop using GET for things like that. Though it may not be in line with the standard, you're very unlikely to get browsers to stop pre-fetching, especially mobile browsers, as it impacts performance pretty significantly. – eyuelt Apr 21 '14 at 17:57
  • 1
    I don't think it has ever been a good idea to use GET for operations different than read-only ones. On MDN `GET` is marked as `Safe`, which means `...it doesn't alter the state of the server. In other words, a method is safe if it leads to a read-only operation.` – undefined Mar 06 '21 at 10:18
  • @boatcoder I can't even find the logout in SO anymore. So I guess the answer to this question is "remove the option to logout". No more need to worry if it is GET or POST. – 2Noob2Good Jan 30 '23 at 23:00
  • 1
    Out of curiosity, browsers are "prefetching" content on your behalf? So basically, Google can crawl apps logged as us. Well, I know they can do whatever they please but still... It feels pretty awkward. It's like the browser implement what they want and if it destroys the behavior of millions of websites it's ok. It's hard to believe. This still happens? I never had any problem with GET logouts. I will start to use POST but still I am quite shocked about all this. – 2Noob2Good Jan 30 '23 at 23:08
  • So, what is the solution when you want to force a logout from code? I have a Blazor server app and so I can't call the UserManager from my code. I need to do a GET on a MVC page that will do it. But then it's a GET. Details at https://stackoverflow.com/questions/76371849/how-can-i-logout-programmatically-identity-in-a-blazor-server-app – David Thielen May 31 '23 at 09:11