Should Logging Out Be a GET or POST? – 注销应该是GET还是POST?

最后修改: 2021年 5月 9日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In a traditional web application, logging in usually requires sending a username and password to the server for authentication. While these elements could theoretically be URL parameters in a GET request, it is obviously much better to encapsulate them into a POST request.

在传统的Web应用中,登录通常需要向服务器发送用户名和密码进行认证。虽然这些元素理论上可以是GET请求中的URL参数,但显然将它们封装在POST请求中要好得多。

However, should logging out be available through a GET request since it does not require any sensitive information to be sent?

然而,既然不需要发送任何敏感信息,是否应该通过GET请求来注销?

In this tutorial, we’ll look at various aspects of this design consideration.

在本教程中,我们将看一下这种设计考虑的各个方面。

2. Server-Side Sessions

2.服务器端会议

When we manage server-side sessions, we must expose an endpoint to destroy those sessions. We may be tempted to use the GET method due to its simplicity. Of course, this will technically work, but it may lead to some undesirable behavior.

当我们管理服务器端的会话时,我们必须公开一个端点来销毁这些会话。我们可能很想使用GET方法,因为它很简单。当然,这在技术上是可行的,但它可能导致一些不受欢迎的行为。

There are some processes like web accelerators that will prefetch GET links for the user. The purpose of prefetching is to immediately serve content when a user follows that link, which cuts down on page loading times. These processes make an assumption that the GET link is strictly for returning content and not for changing the state of anything.

有一些进程,如网络加速器,将为用户预取GET链接。预取的目的是为了在用户跟踪该链接时立即提供内容,从而减少页面加载时间。这些程序假定GET链接是严格用于返回内容的,而不是用于改变任何东西的状态。

If we expose our logout as a GET request and present it as a link, these processes may inadvertently log users out while trying to prefetch links on the page.

如果我们将注销暴露为GET请求,并将其作为一个链接呈现,这些进程可能会在试图预取页面上的链接时无意中注销用户。

This may not be a problem if our logout URL is not statically available, such as being determined by javascript, for example. However, the HTTP/1.1 RFC clearly states that GET methods should only be used to return content and the user cannot be held responsible for any side-effects of a GET request. We should follow this recommendation whenever possible.

如果我们的注销URL不是静态的,例如由javascript决定,这可能不是一个问题。然而,HTTP/1.1 RFC明确指出,GET方法只能用于返回内容,用户不能对GET请求的任何副作用负责。我们应该尽可能地遵循这一建议。

In contrast, the RFC describes the POST method as one that can submit data (our session or session ID) to a data-handling process (logout). This is a more appropriate description of what we are trying to accomplish.

相比之下,RFC将POST方法描述为可以将数据(我们的会话或会话ID)提交给一个数据处理过程(注销)。这是对我们所要完成的任务的更恰当的描述。

2.1. Spring Security

2.1.Spring安全

By default, Spring Security requires the logout request to be of type POST. However, we can cause Spring to use a GET logout request when we disable CSRF protection:

默认情况下,Spring Security 要求注销请求为 POST 类型。但是,当我们禁用CSRF 保护时,我们可以使 Spring 使用 GET 注销请求。

protected void configure(HttpSecurity http) throws Exception {
    http.csrf().disable()
    ...
}

3. Stateless REST

3.无状态REST

When we manage stateless REST sessions, the concept of “logging out” changes. In a stateless environment, every request includes the entire session. Therefore, it is possible to “log out” by simply using Javascript to throw away the session rather than sending any kind of request at all.

当我们管理无状态的REST会话时,”注销 “的概念发生了变化。在无状态环境中,每个请求都包括整个会话。因此,可以通过简单地使用Javascript来丢弃会话,而不是发送任何类型的请求来 “注销”。

However, for security reasons, the server should still be notified of log-out actions in order to blacklist the revoked JWT. This prevents a session from being used after “logging out.”

然而,出于安全原因,服务器仍应被通知注销行动,以便将撤销的JWT列入黑名单。这可以防止会话在 “注销 “后被使用。

Even in a stateless environment, we must still send a request to the server upon logging out. Since the intent of such a request is not to retrieve content, it should not be made via GET. Instead, the session should be POST-ed to the server with the explicit intent to log out.

即使在无状态环境中,我们仍然必须在注销时向服务器发送请求。由于这种请求的目的不是为了检索内容,因此不应该通过GET方式进行。相反,会话应该被POST到服务器上,并明确表示要注销。

4. Conclusion

4.总结

In this short discussion, we’ve briefly looked at the common design question of whether logging out should be a GET or POST.

在这个简短的讨论中,我们简单地看了一下常见的设计问题:注销应该是GET还是POST。

We considered various aspects of this issue:

我们审议了这个问题的各个方面。

  • Semantically, GET requests should not have any stateful side effects
  • There are processes that users might be running in their browser that include prefetching links. If logging out happens over GET, a prefetching process could inadvertently log the user out after logging in
  • Even stateless sessions should report log-out events to the server, which should be done via a POST request