出于学习目的,我创建了一个简单的 PHP 应用程序,它实现了具有基本身份验证机制的 Web 服务。我知道基本身份验证不是最好的机制,但我只想在开始使用 OAuth2.0 或其他东西之前先使用这种机制。
所以我现在的环境是这样的:
多个客户端仅通过 https 连接以 JSON 表示形式提供数据。
- 客户 1:https://example1.com/api/data/
- 客户 2:https://example2.com/api/data/
- ...
这些资源通过基本身份验证 header 进行保护,客户端仅在凭据有效时才提供数据:
public function provideData()
{
if (!isset($_SERVER['PHP_AUTH_USER'])) {
header('WWW-Authenticate: Basic realm="Example BasicAuth"');
header('HTTP/1.0 401 Unauthorized');
die('Authentication failed');
}
$user = $_SERVER['PHP_AUTH_USER'];
$password = $_SERVER['PHP_AUTH_PW'];
// not relevant database stuff ...
$password = hash('sha512', $password . $saltDb);
if (!hash_equals($password, $passwordDb)) {
die('Authentication failed');
}
// not relevant data handling stuff ...
return json_encode($data);
}
因此每个客户端都将自己的凭据存储到客户端数据库中,并且仅当输入的数据有效时才提供数据。 (我不想将凭据作为纯文本存储到客户端数据库中,因此我存储了加盐的哈希密码。)。这对我来说非常有用,但现在我遇到了麻烦:
有一个服务器应该收集所有这些客户端的数据。出于这个原因,我可以在服务器端创建多个客户端对象,其中包含资源 URL、用户名、密码等数据,但我不想将客户端密码作为纯文本存储到服务器数据库中,但我也不能在服务器端存储散列的客户端密码,因为那时服务器将不知道真实密码。
所以我认为唯一的解决方案是实现一个自定义的加密和解密功能,将加密的客户端密码存储到服务器数据库中。那么只有服务器知道加密和解密并可以处理这个问题,或者是否有更好的方法在服务器端存储所需的客户端凭据?
编辑
我将尝试澄清“服务器将不知道真实密码”。如果我错了请打断我,但是基本的 HTTP 身份验证将使用纯客户端数据(用户名和密码)并发送它们的 base64 编码字符串,例如"Authorization: Basic dXNlcjpwYXNzd29yZA=="获取对资源的访问权限。出于这个原因,服务器必须使用明文密码来构建带有基本身份验证 header 的请求。
问题是当我在服务器端创建一个客户端对象时,我必须将凭据存储到服务器数据库中,我可以在那里散列密码,但是散列函数是单向函数,所以服务器不会能够从哈希密码中取回普通密码,而无需存储普通密码,但是如果服务器需要普通密码才能访问资源,那么我不能使用哈希函数将密码“保护”到数据库。
最佳答案
HTTP 基本身份验证需要必须经过 base64 编码的明文凭据。所以服务器必须将每个客户端的明文凭据存储到数据库中,例如,如果这应该有效,但是这真的很糟糕,因为如果有人窃取了服务器数据库,那么他就可以访问所有客户端的数据客户。晦涩难懂,密码通过默默无闻导致安全,并不是真的更好。
所以这是错误的方法。似乎 HTTP 基本身份验证不适合通过 REST API 进行机器对机器通信,我必须使用适当且安全的机制,如 OAuth2.0 或 @ArtisticPhoenix 建议的。
关于php - 如何将基本 HTTP 身份验证的凭据存储到服务器端的数据库中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47114071/