RESTful设计/登录或/注册资源?

时间:2011-08-21 18:06:19

标签: web-services api rest http restful-url

我正在设计一个Web应用程序,然后停下来思考如何将我的api设计为RESTful Web服务。目前,我的大部分URI都是通用的,可能适用于各种网络应用程序:

GET  /logout   // destroys session and redirects to /
GET  /login    // gets the webpage that has the login form
POST /login    // authenticates credentials against database and either redirects home with a new session or redirects back to /login
GET  /register // gets the webpage that has the registration form
POST /register // records the entered information into database as a new /user/xxx
GET  /user/xxx // gets and renders current user data in a profile view
POST /user/xxx // updates new information about user

我有一种感觉,在搜索SO和google后,我在这里做了很多错误。

/logout开始,也许是因为我没有GET任何事情 - POST/logout的请求可能更合适,摧毁会话,以及然后GET重定向。 /logout一词应该留下吗?

/login/register怎么样?我可以将/register更改为/registration,但这不会改变我的服务从根本上如何运作 - 如果它有更深层次的问题。

我现在注意到我从未公开/user资源。也许这可以以某种方式利用。例如,请使用用户myUser

foo.com/user/myUser

foo.com/user

最终用户不需要URI中的额外详细程度。但是,哪一个在视觉上更吸引人?

我在这里注意到关于这个REST业务的一些其他问题,但如果可能的话,我真的很感谢我在这里提出的一些指导。

谢谢!

更新

我还想提出一些意见:

/user/1

VS

/user/myUserName

6 个答案:

答案 0 :(得分:105)

RESTful可用作构建网址的指南,您可以创建会话用户资源:

  • GET /session/new获取具有登录表单的网页
  • POST /session验证针对数据库的凭据
  • DELETE /session销毁会话并重定向到/
  • GET /users/new获取具有注册表单的网页
  • POST /users将输入的信息作为新的/ user / xxx
  • 记录到数据库中
  • GET /users/xxx //在个人资料视图中获取并呈现当前用户数据
  • POST /users/xxx //更新有关用户的新信息

这些可以是复数或单数(我不确定哪一个是正确的)。我通常使用/users作为用户索引页面(如预期的那样),并使用/sessions查看谁登录(如预期的那样)。

使用网址中的名称而不是数字(/users/43/users/joe)通常是希望对用户或搜索引擎更友好,而不是任何技术要求。要么很好,但我建议你保持一致。

我认为如果你选择注册/登录/注销或sign(in|up|out),它就不能与其他术语一起使用。

答案 1 :(得分:55)

有一件事特别突出,因为没有REST-ful:使用GET请求注销。

(来自http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Safe_methods

  

某些方法(例如,HEAD,GET,OPTIONS和TRACE)被定义为安全,这意味着它们仅用于信息检索,不应更改服务器的状态。换句话说,它们不应该具有副作用,除了相对无害的效果,例如日志记录,缓存,横幅广告的提供或递增网络计数器。 [...]

     服务器的[... H]和[GET请求]在技术上没有任何限制。因此,粗心或有意的编程可能会导致服务器上的重大变化。这是不鼓励的,因为它可能导致Web缓存,搜索引擎和其他自动代理[...]

的问题

对于注销和重定向,您可以在注销URI上发布一条帖子,将303响应重定向到注销后页面。

http://en.wikipedia.org/wiki/Post/Redirect/Get

http://en.wikipedia.org/wiki/HTTP_303

编辑以解决网址设计问题:

“我如何设计我的资源?”对我来说是一个重要的问题; “我该如何设计我的网址?”是两个方面的考虑因素:

如果可能,用户将看到的网址不应该太丑陋和有意义; 如果您希望将cookie发送到某些资源而不是其他资源,您需要构建路径和cookie路径。

如果JRandomUser想要查看自己的个人资料,并且您希望网址比foo.com/user/JRandomUserfoo.com/user/(JRandom's numeric user id here)更漂亮,那么您可以创建一个单独的网址,供用户查看他们自己的信息:

GET foo.com/profile /*examines cookies to figure out who 
                     * is logged in (SomeUser) and then 
                     * displays the same response as a
                     * GET to foo.com/users/SomeUser.
                     */

在这个问题上我会比智慧更容易宣称无知,但这里有一些资源设计考虑因素:

  1. 消费者:哪些资源可以直接在浏览器中查看,通过XHR加载,或者由其他类型的客户端访问?
  2. 访问/身份:响应是否依赖于cookie或引用?

答案 2 :(得分:48)

会话不是RESTful

  • 是的,我知道。它正在完成,通常使用OAuth,但实际上会话不是RESTful。您不应该主要拥有/ login / logout资源,因为您不应该有会话。

  • 如果您要这样做,请将其设为RESTful。资源是名词,/ login和/ logout不是名词。我会和/ session一起去。这使得创建和删除成为更自然的行为。

  • POST与GET的会话很容易。如果您将用户/密码作为变量发送,我会使用POST,因为我不希望将密码作为URI的一部分发送。它将显示在日志中,并可能通过电线暴露。您还冒着让GET args限制软件失败的风险。

  • 我通常使用Basic Auth或没有使用REST服务的Auth。

创建用户

  • 这是一个资源,所以你不需要/注册。

    • POST / user - 如果请求者无法指定id
    • ,则创建用户
    • PUT / user / xxx - 假设您事先知道id
    • ,创建或更新用户
    • GET / user - 列出x用户ID
    • GET / user / xxx - 获取id为xxx
    • 的用户的详细信息
    • DELETE / user / xxx - 删除ID为xxx
    • 的用户
  • 使用哪种ID是一个难题。你必须考虑强制执行唯一性,关于重复使用DELETEd的旧ID。例如,如果要回收id(如果可能的话),则不希望在后端使用这些id作为外键。您可以查找外部/内部ID转换,以减轻后端要求。

答案 3 :(得分:20)

答案 4 :(得分:3)

我相信这是一种RESTful身份验证方法。对于LogIn,您使用HttpPut。当提供密钥时,此HTTP方法可用于创建,并且重复调用是幂等的。对于LogOff,您在HttpDelete方法下指定相同的路径。没有使用动词。适当的收集多元化。 HTTP方法支持此目的。

[HttpPut]
[Route("sessions/current")]
public IActionResult LogIn(LogInModel model) { ... }

[HttpDelete]
[Route("sessions/current")]
public IActionResult LogOff() { ... }

如果需要,您可以将当前电流替换为活动状态。

答案 5 :(得分:2)

我建议使用类似于Twitter的用户帐户网址,其中用户的帐户网址类似于foo.com/myUserName,就像您可以使用网址https://twitter.com/joelbyler

访问我的Twitter帐户一样

我不同意退出需要POST。作为API的一部分,如果您要维护会话,那么UUID形式的会话ID可能会用于跟踪用户并确认正在采取的操作是否已获得授权。然后即使是GET也可以将会话ID传递给资源。

简而言之,我建议您保持简单,URL应该简短而难忘。