为PHP REST API实现简单身份验证

Nil*_*ils 10 php authentication api rest session

我正在努力为旧版PHP站点添加REST API.这是为内部应用程序提供端点,所以我可以自由地设计内容以及支持哪些内容.

我现在需要添加到此API的是一种登录方式,然后以特定用户身份执行操作.该网站已在几年前建成,并不一定是当时的最佳实践,所以我很遗憾对我的工作方式有点限制.所有这些都需要使用MySQL 5.6在PHP 5.4中运行.

我一直在阅读常见的设计,OAuth1/2看起来像是最常见的标准.然而,对于我的目的来说,这似乎是一种巨大的矫枉过正,因为它具有我不需要的各种功能,并且实现起来似乎非常复杂.

相反,我正计划做这样的事情:

  • 客户端调用get_sessionAPI端点,该端点生成随机会话ID,将其保存到数据库中的表并将其返回给客户端.
  • 客户端保存此会话ID.
  • 然后客户端通过向login端点发送请求进行身份验证,发送用户名,密码和会话ID(显然通过HTTPS).
  • 服务器将数据与用户表进行比较,如果登录正确,则更新会话表以将会话ID与相应的用户ID相关联.这需要以某种方式限制速率以防止暴力强制.
  • 现在,客户端可以调用任何其他端点,仅提供其会话ID以进行授权.
  • 在每个请求中,服务器查找会话ID,查看与之关联的用户并执行正确的操作.
  • 客户端可以记住会话ID以供将来使用,直到它被手动删除或在一段时间后过期.
  • 要注销,客户端会向logout端点发送请求,服务器会删除与用户帐户的关联.

这是一个合理的设计吗?它显然不是很复杂,但我正在寻找一些我可以实现的东西,没有太大的麻烦或需要第三方库.

Sam*_*tch 20

REST作为一个概念的一个主要观点是避免使用会话状态,以便更容易水平扩展REST端点的资源.如果您计划在$_SESSION问题中概述使用PHP ,那么在您想要扩展的情况下,您将发现自己处于难以实现共享会话存储的困境中.

虽然OAuth将是您想要做的首选方法,但完全实现可能比您想要的更多工作.但是,您可以创建一些半测量,但仍然保持无会话.你以前可能甚至看过类似的解决方案.

  1. 配置API帐户时,会生成2个随机值:令牌和密钥.
  2. 当客户提出请求时,他们提供:
    • 令牌,明文.
    • 从唯一但已知值和Secret计算的值.例如:HMAC或加密签名
  3. 然后,REST端点可以维护Tokens和Secrets的简单,集中的键值存储,并通过计算值来验证请求.

通过这种方式,您可以保持"无会话"REST的理想状态,并且您在交换的任何部分都不会实际传输秘密.

客户示例:

$token  = "Bmn0c8rQDJoGTibk";                 // base64_encode(random_bytes(12));
$secret = "yXWczx0LwgKInpMFfgh0gCYCA8EKbOnw"; // base64_encode(random_bytes(24));
$stamp  = "2017-10-12T23:54:50+00:00";        // date("c");
$sig    = hash_hmac('SHA256', $stamp, base64_decode($secret));
// Result: "1f3ff7b1165b36a18dd9d4c32a733b15c22f63f34283df7bd7de65a690cc6f21"

$request->addHeader("X-Auth-Token: $token");
$request->addHeader("X-Auth-Signature: $sig");
$request->addHeader("X-Auth-Timestamp: $stamp");
Run Code Online (Sandbox Code Playgroud)

服务器示例:

$token  = $request->getToken();
$secret = $auth->getSecret($token);
$sig    = $request->getSignature();

$success = $auth->validateSignature($sig, $secret);
Run Code Online (Sandbox Code Playgroud)

值得注意的是,如果决定使用时间戳作为nonce,则应该只接受在最后几分钟内生成的时间戳,以防止重放攻击.大多数其他身份验证方案将在签名数据中包括其他组件,例如资源路径,标头数据的子集等,以进一步锁定签名以仅应用于单个请求.

  • 我会说那个错误是(•_•)/(•_•)>⌐■ - ■/(⌐■_■)@HardlyNoticeable.******YEEEEEAAHHHHHHHHH (7认同)

小智 0

好吧,您写了很多如何从头开始发明 cookie 以及如何将它们存储在数据库中的文章。

同时,您已经拥有用于安全数据传输的用户名、密码和 HTTPS。为什么不只使用 cookie?