在RESTful webservice中实现登出

7

我在开发一款移动应用程序,需要一个注销服务。登录服务已经通过从数据库进行验证完成,现在我卡在了注销上。


1
这取决于“已登录”会话是如何表示的。通常,它是通过在浏览器中存储的cookie中存储的令牌来实现的。如果是这种情况,那么令牌只需要过期/删除/清除即可。 - sisyphus
你如何实现登录服务?你使用Spring MVC或任何Java Web技术吗? - yelliver
@yelliver 用于登录服务,我正在检查用户名和密码的详细信息与数据库记录。如果计数为1,则已登录。否则返回错误。 - user6325753
4
从RESTful Web服务注销并没有意义。(无状态) - Toilal
3个回答

10

退一步

你没有提供关于应用程序如何进行身份验证的详细信息,很难猜测你在做什么。

然而,在REST应用程序中,服务器端不应存储任何 会话状态 ,而是必须由客户端 完全处理会话状态

但是服务器端会话状态有什么问题呢?它们是 有状态的 ,并且会破坏 REST 无状态约束 (阅读更多细节),因此它不符合 REST 的要求。

无状态约束

根据 Roy T. Fielding 的 论文,REST 无状态约束 定义为以下内容:

5.1.3 无状态

[...] 客户端到服务器的每个请求必须包含理解该请求所需的所有信息,并且不能利用服务器上的任何存储上下文。因此,会话状态完全保留在客户端中。 [...]

例如,在访问需要身份验证的受保护资源时,每个请求都必须包含 所有必要的数据以正确进行身份验证/授权。并且认证数据应属于标准的 HTTP Authorization 头。根据 RFC 7235

4.2. Authorization

Authorization 头字段允许用户代理使用起源服务器进行身份验证——通常是在收到 401(未经授权)响应后。它的值由包含用户代理的身份验证信息的凭据组成,用于所请求资源的领域。 [...]

总结

REST是无状态的。没有登录或注销,不涉及“会话”。每个需要身份验证的资源请求都必须携带身份验证数据。会话状态保存在客户端而不是服务器端。


6
您需要两个网络服务,一个用于登录,另一个用于注销。在用户退出应用程序时,您需要调用注销服务。
具体而言,您需要在数据库中管理一个标志。当正确的用户名和密码通过登录网络服务传递时,该标志将为true。在注销服务中,您只需要发送用户名并将标志更新为false。以此方式,如果您在用户名和密码中同时发送移动设备的IMEI号码到登录服务中,还可以防止多次登录。

@Mithlesh,感谢您的快速回复。如果可能的话,您能提供任何有关在数据库中管理标志的教程吗?因为这是我第一次听到数据库中的标志概念。 - user6325753
你需要添加一列,将其命名为“session”或其他名称,类型为整数型。当用户登录时,将其更新为1,当用户登出时,将其更新为0。@ccc2607 我使用这种方法来防止多次登录。 - Mithilesh Izardar
这个概念需要手机的IMEI号码吗?或者没有IMEI号码也可以实现吗? - user6325753
IMEI号不是必需的,我使用它来判断用户是从同一设备登录还是不同设备。 - Mithilesh Izardar
请检查您的邮件 @ccc2607 - Mithilesh Izardar
请勿将此标记为答案。仔细阅读主题:“在RESTful webservice中实现注销”。RESTful意味着无状态。这意味着在身份验证过程中不应执行任何类似于数据库调用的操作。如果您不确定问题是什么,请不要回答。 - user11814208

3

通常情况下,登录应该返回令牌或cookie(如果不是REST风格)。

注销时,令牌应该被作废。

如果使用的是cookie,则可以先在服务器端使会话无效,然后在客户端删除cookie。

针对您的问题,您可以在登录后生成一个新的令牌(唯一随机),并将其保存在新列中,在连续的请求中期望相同的令牌而不是布尔标志。

为了基本的注销,您只需要为该用户删除该令牌。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接