我在节点中编写了一个使用HATEOAS的REST API。用户必须先拥有一个帐户才能访问其中的大部分帐户。
他们使用登录详细信息注册帐户,然后登录以获取访问令牌,然后使用该令牌访问任何不是register
或login
的端点。
向根发出get
会回复一个包含可用操作的目录。
问: register
的正确回复是什么,告诉客户下一步该做什么(即登录)?
register
从技术上讲,会在服务器上创建一个新资源,因此201 CREATED
和Location
标题似乎是合适的。但是,login
引用并不是新创建资源的位置。
我应该返回201 Created
,Location
指向新创建的用户(例如/myaccount
或/users/{id}
,然后在响应正文中包含登录链接
{ _links: { self: { href: "what goes here?" }, x:login: { href: "/login" } } }
get
以获取可用端点列表。无论如何,这应该包括login
。假设客户端必须首先获取register
链接,它应该已经login
。 期望客户已经拥有登录链接感觉不舒服,因为它依赖于客户先前活动的假设。
要求客户端在注册后向根目录发出另一个请求似乎是卑鄙,低效和不必要的。如果客户端刚刚创建了一个资源,那么服务器应该用它接下来可以做什么来回应它,这似乎是公平的。
答案 0 :(得分:0)
我喜欢让我的api行为与网页没有什么不同。如果您希望应用程序的用户体验是用户在注册后进行登录,则将302从成功注册到登录资源。并且在成功登录后,302将它们发送到适当的目的地(IE,如果他们试图访问没有令牌的东西,则将它们带到登录,具有原始请求资源的目的地)。对你的#3来说,这是重要的一部分。在根目录之外有一个导致登录的链接,但是您需要保护所有其他链接,以便它们指示(并链接到)访问资源所需的登录。客户端应用程序应该随时获得此登录所需的响应,因为令牌可以(并且确实)随时到期。
在此之后,将JWT作为cookie而不是作为授权标题进行操作可能是有意义的,它会使客户端更容易(他们只需要设置一个cookie jar)..如果客户端是一个维持单一连接设置的原生移动应用程序。如果它是服务器到服务器,那么auth头是有意义的。我会同时支持这两种方案。
继续将api视为网站的想法。为什么要在注册后登录?为什么不注册帐户最终会发送登录令牌?他们只是设置他们的用户/通行证,为什么让他们再次输入?我意识到一些更奇特的架构,注册服务无法执行登录操作(也许它没有私钥来签署令牌),但如果有可能我会考虑它。
如果你真的想坚持201标题(这很好,只要确保你的注册关系的文档表明这一点),那么选项2是我认为最接近的。刚创建201的帐户的URL的位置标头是创建用户的标准。但是,我不会回复你所认为的那些东西。您可以返回帐户创建的资源(具有登录链接的东西),但您真的需要此自定义资源吗?如果您想在该资源中向客户端发送一些消息(例如" Account Created"),那么绝对可以,但您也可以将它们返回给根资源。
TL;博士;确定您希望用户体验的内容,然后让您的API实现您的用户体验。