在PHP中实现身份验证API


Implement authentication API in PHP

我有一个现有的Django应用程序(D),我想连接一个PHP应用程序(p,在不同的服务器上)进行身份验证。也就是说,用户登录到D,它调用P上的服务来检查他们的密码。他们还需要最终拥有一个本地用户帐户,并将有关他们的属性存储在D中。实际的安全要求非常低。D很难直接访问P的数据库。

从未实现过任何身份验证,我想到了这样的东西:

  1. D: 收集用户名和密码,计算哈希(使用与P相同的算法)
  2. D: 在P上调用web服务(HTTP),传递用户名和哈希
  3. P: 查找用户名,如果不存在则失败
  4. P: 如果是,请对照传递的哈希检查存储的哈希,如果不同,则失败
  5. P: 如果可以,返回有关用户的其他信息(例如,全名,一些特定于域的信息),否则返回失败
  6. D: 如果可以,创建/更新用户记录
  7. D: 如果可以,请将其登录

因此,有几个问题:

  • 这种做法明智吗?它容易受到什么攻击(通知客户…)
  • 您将在P:身份验证提供商处添加的功能称为什么
  • 有没有一种更标准的方法来做这些事情,使用标准协议,或者至少使用web服务调用名
  • 步骤6是否合理?以这种方式同步用户数据库有缺点吗

由于您已经提到两台服务器位于同一机构/网络中,因此只要您使用HTTPS而不是纯HTTP,身份验证就可以工作。

D: Collect username and password, compute hash (using same algorithm as P)

除非您能够确定PHP哈希与Django哈希相同,否则我建议您通过(但不要通过纯HTTP,请参阅第2点)发送密码。

Call web service (HTTP) on P, passing username and hash

只有当您绝对确定这两个服务器是直接连接的时,才应该使用纯HTTP。否则,你很容易受到典型的网络攻击(例如,中间人),你会以明文形式传输(哈希)密码。我假设在PHP应用程序端,您直接验证哈希是否相同。如果不确定网络条件,请确保通过HTTPS调用web服务。

P: Look up username, fail if it doesn't exist.
P: If it does, check stored hash against passed hash, fail if different.
P: If ok, return some other information about the user (eg, full name, some domain-specific stuff), otherwise return fail
D: If ok, create/update the user record
D: If ok, then log them in.

这些步骤很好,但如果您希望在两个数据库之间实现持续的用户同步,则需要找到更新自己的用户数据库的方法。如果PHP应用程序禁用/删除了一个用户,Django应用程序需要接受这个更改,否则你仍然允许被删除的用户登录Django。

有两种方法可以解决这个问题:

  1. 每X分钟/小时轮询一次,以验证用户状态是否相同
  2. 使用消息传递系统(例如RabbitMQ),这样PHP端的每一个更改都会在Django端发布和接收

第一种方法更简单,但没有那么高效和安全,因为用户仍然可以在下一次轮询之前登录Django端。如果安全性不重要,并且只有少量用户,则建议这样做。

第二种方法更好,但您必须编写更多的代码来管理同步(PHP和Django)。这种方式要好得多,因为你可以几乎立即跟踪PHP应用程序中的用户更改,并将其反映在你自己的数据库中。如果用户没有使用你的Django应用程序,你可以忽略PHP端用户的更改(因此你端没有记录)。