【问题标题】:PHP REST API LogicPHP REST API 逻辑
【发布时间】:2013-01-20 07:10:19
【问题描述】:

我最近阅读了一些教程来介绍自己以了解更多关于其余 API 的信息。但是,我在这里和那里有些疑问,希望有人可以帮助我解决这个问题。

阅读Beginner's Guide to HTML and REST,其中指出:

“最好将资源视为名词。例如,以下不是 RESTful:

1 /clients/add

这是因为它使用 URL 来描述操作。这是区分 RESTful 和非 RESTful 系统的一个相当基本的点。”

因此,我想知道在我拥有用户资源并访问它以执行通常的插入/更新/删除/检索的这种情况下

如下:

www.example.com/users [get] www.example.com/users/1 [get] www.example.com/users/1 [put] www.example.com/user/1 [delete] www.example.com/user [post]

这会用完 4 个常用动词来发出请求。

如果我需要诸如登录之类的功能,或者一般来说可能需要任何其他类型的操作命令,该怎么办? url应该如何形成,这种情况下路由器应该如何重定向?

编辑:

在查看了各种 cmets 和答案之后。我从他们那里得到的结论是,最终的解决方案将是“尽可能使用休息原则,并在不使用时使用带有函数的查询字符串方法”。

但是,我正在考虑实现的一个轻微变体(不再是一个安静的实现,而是遵循类似的概念)并且想知道它是否可以这样工作。希望大家给我建议。

使用我需要实现的相同身份验证/登录功能,是否可以改为:

www.example.com/users [get] www.example.com/users/1 [get] www.example.com/users/1 [put] www.example.com/user/1 [delete] www.example.com/user [post]

像往常一样,如果我需要执行某项操作,它将是这样的:

[controller]/[action] --- 用户/验证 [post] --- 登录
[controller]/[id]/[action] --- user/1/authenticate [put] --- 注销

这行得通吗?我会面临任何可预见的问题吗?是否已经有类似的实现?请多多指教!

【问题讨论】:

  • 登录功能不适合 REST 范式。
  • @leftclickben 感谢您的回复。这样,我应该如何使用 REST Api 实现登录/身份验证功能?这是否也适用于所有一般方面?例如需要为特定资源创建一些操作/功能(而不是直接从资源中插入/更新/删除/检索信息?
  • 好吧,请参阅 Neville K 的回答,但在我看来,使用 REST 进行登录是试图塞入一些不适合的东西。在需要时使用 REST,不要在任何情况下都强加于自己 :-)
  • @leftclickben 是否意味着解决方案最终会有各种形式的api请求?就像使用 REST 对资源进行检索/插入/更新/删除一样,而操作使用通常的方法,例如在 url 或 post 中传递参数以及执行操作的函数名称?
  • 是的,你是对的,但我认为这是登录和 REST 所固有的。在 REST 中,您正在访问资源,并且您有 8 种不同的操作,具体取决于您使用的方法以及您是点击集合还是元素。所有这 8 种方法都没有映射到登录,事实上它们都没有特别干净地映射。登录和注销显然是动作,虽然这些动作的实现需要资源,但动作本身并不直接映射到任何资源。

标签: php web-services api http rest


【解决方案1】:

有些动作很难以真正的 RESTful 方式建模 - 但登录,例如,可以使用以下伪代码实现:

GET the user rights whose userID is x and password is y
if (user rights found)
  assign rights to current user
else
  do not assign rights to user

请参阅this question 了解如何检索用户权限。这个问题的重点是您通常需要多种方式来访问您的资源。有些是基于 ID 或众所周知的属性,例如:

  • www.example.com/users/department [get](获取一个部门的所有用户)
  • www.example.com/users/roleName [get](获取特定角色的所有用户)
  • www.example.com/users/status/active [get](获取所有“活跃”用户)

但是,某些访问用户的方式(尤其是当您需要组合两个或多个过滤属性时)使用查询字符串参数更易于管理。例如:

www.example.com/users?department=xxx&role=yyy&status=active [获取]

因此,您的 REST API 可能会按照以下方式公开一个 URL:

www.example.com/users?userName=xxxx&password=yyy [获取]

此 URL 将根据用户数据库匹配用户名和密码参数,并返回 404(如果它们与已知用户不匹配)或代表用户的文档及其访问权限。

然后您的客户端代码管理当前用户的会话 - 即将状态设置为“登录”,并将会话与该用户配置文件相关联。

完成这项工作的关键是将责任分配给正确的层 - API 不应该管理用户会话,这是客户端应用程序的责任。在某些情况下,它的效果并不特别好——不过,不确定你的情况是否如此。

如果您真的想使用 POST 请求,当然可以将“登录”方法视为该用户会话的开始。因此,您可以这样做:

www.example.com/session [POST] 带有参数用户 ID 和密码。

这将返回用户配置文件和权限的表示;它还可以创建可在 URL 下访问的文档

www.example.com/session/sessionID

www.example.com/session/user/ID/session

但是,一般来说,在 API 中管理会话状态是一个非常危险的想法 - 几乎总是,您希望客户端会话由与客户端交互的应用程序管理,而不是由它与之交谈的 API 管理。

【讨论】:

  • 感谢您的回复。我希望我已经理解您正确链接的问题。它解释了将参数传递给服务器的两种不同方法,以及哪种做法更适用于任何目的。如果我的解释有误,请纠正我。但是,我很想知道应该如何通过 REST 概念执行/执行操作。或者可能像 leftclickben 和你提到的那样,有些动作很难以真正的 RESTful 方式建模,而应该以正常方式完成?
  • 我会更新答案以澄清 - 但很多人会争辩说 RESTful 正常的方式!
  • 谢谢!可能这里的“正常”这个词有点模棱两可。因为我一直在尝试使用的通常方法是相应地发送 post/get 请求,并在 url 中使用函数参数说明它应该执行脚本中的哪个函数。
  • 这是否也意味着在用户控制器文件中,我必须监听传入的各种类型的参数并做出相应的反应?
  • 更新答案 - 但是,是的。
【解决方案2】:

如果我需要登录或登录等功能怎么办? 一般任何其他类型的动作命令? url应该怎么写 在这种情况下,路由器应该如何重定向?

拥有 login-action 资源不是 RESTful,但提供 login-form 资源 RESTful:

/login-form

您在响应中返回的 HTML 表单作为 code-on-demand;您正在提供一个已配置的软件来帮助用户提供他们的登录凭据。

将资源标识为 /login 不会有任何问题 - 我添加了表单部分以使示例清晰。

您应该避免在需要身份验证的情况下进行重定向,因为它会破坏 Web 浏览器以外的客户端的界面;相反,您可以:提供登录表单的链接;或实际在响应中提供登录表单代码。

如果你想管理身份验证,我更喜欢创建身份验证令牌的方法;对于 Web 浏览器,我认为重载单个 cookie 是可以接受的,目的是帮助客户端为每个请求提供令牌,因为他们没有其他合理的方式来控制他们的 Auth 标头发送;显然,如果您正在编写自己的客户端应用程序,这不是问题。

在下面回答你的 cmets,auth-token 场景中登录表单的目的是创建一个新的身份验证令牌。因此,以 REST 的方式思考,您对 auth-token 的用户列表进行建模并发布 auth-token 的表示。此表示可能包含用户的用户名和密码。您可以让用户选择他们自己的令牌,或者您可以为他们选择它并在响应中返回它。不需要 action-URI,并且在成功创建新的 auth-token 后设置任何 cookie。

我建议学习 Amazon S3 REST API。它与您的要求略有不同,但它是我所见过的对潜在 REST 身份验证系统的最佳深入描述:

http://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAPI.html

您关于以 REST 方式管理用户的想法是准确的。

希望对你有帮助:)

【讨论】:

  • 感谢您的回复。我只是好奇,通过向客户端发送表单或链接,它是否仍然需要一个函数来接受操作字段中表单的返回值?
  • 是的,我正在考虑使用身份验证令牌概念,我将在客户端(cookie)存储用户的 id 和身份验证令牌,他将在探测之前发送这两个必要的信息数据接口。
  • 更新的答案.. 希望涵盖它?
【解决方案3】:

REST 是无状态的,因此您需要将所有需要的信息放入所有查询中。我们的想法是使用 HTTP 动词(GET、PUT、DELETE、POST - 正如您已经描述的那样)。

如果您想要对您的 REST API 进行用户身份验证,请使用 HTTP 基本身份验证或您自己的身份验证。您必须将每个请求的身份验证信息发送到服务器(无状态)。

如果您不想要 HTTP 基本身份验证,您可以尝试一些令牌身份验证或任何其他身份验证。

编辑:如果您想要“检查登录”资源,请构建您自己的资源。 例如带有 http 基本身份验证标头信息的 GET /account/checklogin。此请求的结果取决于您的身份验证信息。

【讨论】:

  • 感谢您的回复!是的,我正在考虑使用我自己的身份验证令牌并为每个请求发送它以使其无状态。但是,对于某些资源,我仍然需要一些“操作”。这仍然使它成为无状态的吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-10-18
  • 1970-01-01
  • 2014-09-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多