简体   繁体   English

创建用户帐户时正确的HATEOAS响应

[英]Correct HATEOAS response when creating a user account

I have a REST api written in node which uses HATEOAS. 我有一个使用HATEOAS编写的REST api节点。 The user is required to have an account before they can access the bulk of it. 用户必须先拥有一个帐户,然后才能访问其中的大部分帐户。

They register an account with login details, then login to obtain an access token, and then use that token in order to access any endpoints that aren't register or login . 他们使用登录详细信息注册一个帐户,然后登录以获得访问令牌,然后使用该令牌访问未registerlogin任何端点。

Issuing a get to the root responds with a directory with available actions. 向根目录发出get命令将响应一个包含可用操作的目录。

Q: What is the correct response from register , to tell the client what it can do next (ie login)? 问: register的正确响应是什么,告诉客户端下一步可以做什么(即登录)?

  1. register technically creates a new resource on the server so a 201 CREATED and a Location header would seem appopriate. register技术上讲, register在服务器上创建了一个新资源,因此201 CREATEDLocation标头似乎是合适的。 However the login reference isn't the location of the newly created resource. 但是, login参考不是新创建的资源的位置。

  2. Should I return 201 Created with a Location pointing to the newly created user (eg /myaccount or /users/{id} and then include a login link in the response body? 我是否应该返回201 Created ,其Location指向新创建的用户(例如/myaccount/users/{id} ,然后在响应正文中包含登录链接?

{
        _links: {
            self: { href: "what goes here?" },
            x:login: { href: "/login" }
        }
    }
  1. Do I not tell the client at all, and require them to do a get on the application root in order to fetch a list of available endpoints. 难道我没有告诉客户所有,并要求他们做一个get ,以获取可用的端点列表上的应用程序的根。 This should include login anyway. 无论如何,这应该包括login Assuming the client had to do that in the first place to get the register link it should already have login . 假设客户首先必须这样做才能获得register链接,那么它应该已经login

Expecting the client already to already have the login link feels uncomfortable as it relies on an assumption of the client's prior activity. 期望客户已经具有登录链接感到不舒服,因为它依赖于客户先前活动的假设。

Requiring the client to issue another request to the root directory after registering seems mean, inefficient and unnecessary. 注册后要求客户端向根目录发出另一个请求似乎很卑鄙,低效且不必要。 If the client has just created a resource it seems only fair that the server should respond with what it can do with it next. 如果客户端刚刚创建了资源,则服务器应该响应下一步可以做什么,这似乎很公平。

I like to have my api's act no differently than a webpage. 我希望自己的api行为与网页相同。 If you want the UX of your application to be the user is taken to login after they register, then 302 them from a successful register to the login resource. 如果您希望应用程序的UX成为用户注册后的用户,则从成功注册302到登录资源。 And upon successful login, 302 to them to the appropriate destination (IE, if they tried to access something with no token, then take them to login, with a destination of the original requested resource). 并且在成功登录后,将他们302到适当的目的地(即,IE,如果他们尝试访问没有令牌的东西,则将其带原始请求资源的目的地登录)。 That's and important part to your #3. 这是您#3的重要组成部分。 Having a link off the root that leads to login, but you need to protect all the other links such that they indicate (and link to) a login being required to access the resource. 在根目录下有一个链接可以导致登录,但是您需要保护所有其他链接,以便它们指示(和指向)访问资源所需的登录名。 The client app should expect to get this login required response at any time as tokens can (and do) expire at any time. 客户端应用程序应该期望在任何时候获得此登录要求的响应,因为令牌可以(并且确实)在任何时间过期。

Following on this, it might make sense to do the JWT as a cookie instead of as an Authorization Header, it would make it a bit easier for the client (they just have to setup a cookie jar)..if the client is say a native mobile app that maintains a single connection setup. 接下来,将JWT作为cookie而不是Authorization Header做为有意义,这将使客户端变得更加容易(它们只需要设置一个cookie jar)。维护单个连接设置的本机移动应用程序。 If it's server to server, then auth header makes sense. 如果是服务器对服务器,则auth标头有意义。 I'd go about supporting both to cover both scenarios. 我将同时支持这两种情况。

Continuing on the idea of thinking of the api as a web site. 继续将api视为网站的想法。 Why have them login after registration at all? 他们为什么要在注册后完全登录? Why not have the registering of an account end up with the login token being sent? 为什么不以发送登录令牌结束帐户注册? they just set their user/pass, why make them enter it again? 他们只是设置了用户名/密码,为什么要让他们再次输入? I realize with some more exotic architectures the register service can not perform the login action (perhaps it doesn't have the private key to sign the token), but if it is possible i'd consider it. 我意识到,在一些更奇特的体系结构中,注册服务无法执行登录操作(也许它没有用于签名令牌的私钥),但如果可能的话,我会考虑使用它。

If you really want to stick to the 201 header (which is fine, just make sure the docs of your register relationship indicate that), then option 2 is the closest in my opinion. 如果您真的想坚持使用201标头(这很好,只需确保您的注册关系文档表明了这一点),那么我认为选项2是最接近的。 A location header to the URL of the account just created a 201 is pretty standard for creating a user. 刚创建201的帐户URL的位置标头是创建用户的相当标准。 But, i'd not return what you've supposed there. 但是,我不会返回你在那儿应该做的事情。 You're kind of returning a account-created resource (the thing with the login link), but do you really need this custom resource? 您有点返回帐户创建的资源(带有登录链接的东西),但是您真的需要此自定义资源吗? If you want to give some messaging back to the client (like "Account Created") in that resource then absolutely yes, but you could also just give them back the root resource. 如果您想在该资源中将某些消息返回给客户端(例如“创建帐户”),则绝对可以,但是您也可以将它们还给根资源。

tl;dr; TL;博士; Decide what you want your UX to be and then make your API implement your UX. 确定您想要的用户体验是什么,然后使您的API实现您的用户体验。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM