免责声明:我是 REST 学派的新手,我正试图围绕它展开思考。
所以,我正在阅读这个页面,Common REST Mistakes,我发现我完全被与会话无关的部分所困惑。这是页面上所说的:
客户端应该不需要“登录”或“开始连接”。 HTTP 身份验证在每条消息上自动完成。客户端应用程序是资源的消费者,而不是服务。因此没有什么可以登录的!假设您要在 REST Web 服务上预订航班。您不会创建与服务的新“会话”连接。相反,您要求“行程创建者对象”为您创建一个新行程。您可以开始填写空白,然后在网络上的其他地方获取一些完全不同的组件来填写其他空白。没有会话,因此在客户端之间迁移会话状态没有问题。服务器中也没有“会话亲和性”问题(尽管仍有负载平衡问题需要继续)。
好的,我知道每条消息都会自动完成 HTTP 身份验证 - 但是如何呢?用户名/密码是否随每个请求一起发送?这不只是增加了攻击面吗?我觉得我错过了拼图的一部分。
拥有一个接受 GET 请求的 REST 服务(例如 /session
)会很糟糕,您将在其中将用户名/密码作为请求的一部分传递,并在身份验证成功时返回会话令牌,那然后可以与后续请求一起传递吗?从 REST 的角度来看,这是否有意义,还是没有抓住重点?
要成为 RESTful,每个 HTTP 请求本身都应该携带足够的信息,以供其接收者处理它,以与 HTTP 的无状态特性完全一致。
好的,我知道每条消息都会自动完成 HTTP 身份验证 - 但是如何呢?
是的,用户名和密码随每个请求一起发送。这样做的常用方法是基本访问身份验证和摘要访问身份验证。是的,窃听者可以捕获用户的凭据。因此,人们将使用传输层安全性 (TLS) 加密所有发送和接收的数据。
拥有一个接受 GET 请求的 REST 服务(例如 /session)会很糟糕,您可以在其中将用户名/密码作为请求的一部分传递,并在身份验证成功时返回会话令牌,这可以然后与后续请求一起传递?从 REST 的角度来看,这是否有意义,还是没有抓住重点?
这不是 RESTful,因为它带有状态,但它很常见,因为它为用户提供了便利;用户不必每次都登录。
您在“会话令牌”中描述的内容通常称为登录 cookie。例如,如果您尝试登录 Yahoo!帐户有一个复选框,上面写着“让我登录 2 周”。这本质上是说(用你的话来说)“如果我成功登录,让我的会话令牌保持活动状态 2 周。” Web 浏览器将在您要求它为您发出的每个 HTTP 请求中发送此类登录 cookie(可能还有其他)。
REST 服务要求对每个 HTTP 请求进行身份验证的情况并不少见。例如,Amazon S3 要求每个请求都具有从用户凭证、要执行的确切请求和当前时间派生的签名。这个签名在客户端很容易计算,可以被服务器快速验证,对拦截它的攻击者使用有限(因为它是基于当前时间的)。
许多人不太清楚 REST 原则,使用会话令牌并不意味着您总是有状态的,每个请求发送用户名/密码的原因仅用于身份验证,发送令牌也是如此(由登录生成过程)只是为了决定客户端是否有权请求数据,当您使用用户名/密码或会话令牌来决定要显示哪些数据时,您只会违反 REST 约定!相反,您必须仅将它们用于身份验证(显示数据或不显示数据)
在您的情况下,我说是的,这是 RESTy,但请尝试避免在您的 REST API 中使用本机 php 会话并开始生成您自己的散列令牌,这些令牌在确定的时间段内到期!
不,它没有错过重点。 Google 的 ClientLogin 正是以这种方式工作的,但值得注意的例外是客户端被指示使用 HTTP 401 响应进入“/session”。但这不会创建会话,它只会为客户端(临时)在不以明文方式传递凭据的情况下进行身份验证,并让服务器在它认为合适的情况下控制这些临时凭据的有效性。
好的,我知道每条消息都会自动完成 HTTP 身份验证 - 但是如何呢?
“授权:”客户端发送的 HTTP 标头。基本(纯文本)或摘要。
拥有一个接受 GET 请求的 REST 服务(例如 /session)会很糟糕,您可以在其中将用户名/密码作为请求的一部分传递,并在身份验证成功时返回会话令牌,这可以然后与后续请求一起传递?从 REST 的角度来看,这是否有意义,还是没有抓住重点?
会话的整个想法是通过在服务器端维护状态来使用无状态协议(HTTP)和哑客户端(Web 浏览器)来制作有状态应用程序。 REST 原则之一是“每个资源都可以使用用于超媒体链接的通用语法进行唯一寻址”。会话变量是不能通过 URI 访问的东西。真正的 RESTful 应用程序将在客户端维护状态,通过 HTTP 发送所有必要的变量,最好是在 URI 中。
示例:分页搜索。您将在表单中有 URL
http://server/search/urlencoded-search-terms/page_num
它与可收藏的 URL 有很多共同点
如果您想控制客户端会话的生命周期,我认为您的建议是可以的。我认为 RESTful 架构鼓励您开发无状态应用程序。正如@2pence 所写的那样,“每个 HTTP 请求本身都应该携带足够的信息,以便其接收者对其进行处理,以与 HTTP 的无状态特性完全一致”。
但是,情况并非总是如此,有时应用程序需要告知客户端何时登录或注销,并根据此信息维护诸如锁或许可证之类的资源。有关此类情况的示例,请参阅我的跟进 question。