我目前正在计划重组一个Web应用程序,以将API与应用程序分开。 现在,用户通过在标准HTML表单中输入其操作员ID(用户名)和密码来登录应用程序,并通过检查数据库表并创建PHP会话(使用Zend_Session
处理)来完成身份验证。我不确定在分离 API 后如何继续执行此操作。
以下是一些简化的代码来说明当前的工作方式:
// GET https://foo.example.com/module/trips.php
if (isLoggedIn() && isAuthorized($SESSION->operatorID)) {
require 'views/trips.php';
}
// POST https://foo.example.com/module/trips.php?action=take
// ...
// this request can come from AJAX, for example
if (isLoggedIn() && isAuthorized($SESSION->operatorID)) {
$model->assignTrip($SESSION->operatorID, $_POST['trip_id']);
}
显然,这不是很休息,因此努力将两者分开。这是我提出的(仍在进行中):
// GET https://api.foo.example.com/v1.0/trips
echo json_encode($model->getAllTrips());
// POST https://api.foo.example.com/v1.0/trips/:trip_id/operator
$model->assignTrip($_POST['operator_id'], $trip_id);
我知道 REST 是无状态的。在此简化示例中,只有操作员才能为自己分配行程。如何使用 API 强制执行此功能?
我已经阅读了很多关于使用 REST API 进行身份验证的问题和文章,他们都在谈论 OAuth/OAuth2,它似乎非常适合通过令牌对 API 的客户端进行身份验证,但没有关于对 API 客户端的用户进行身份验证(或者也许我误解了什么?就我而言,我的 API 客户端仍然是 Web 应用程序。
我的主要问题:API 应该如何确定用户是谁?或者它甚至应该?
或者,我已经考虑在 Web 应用程序中执行此操作:
// POST https://foo.example.com/module/trips.php?action=take
// ...
// this request can come from AJAX, for example
if (isLoggedIn() && isAuthorized($SESSION->operatorID)) {
// Use cURL to send an HTTP POST request with the appropriate data to
// https://api.foo.example.com/v1.0/trips/6/operator
}
这似乎是不必要的开销,但这就是这个答案的样子。我认为在我重组之后,我应该从JavaScript中做这样的事情:
$.ajax({
type: 'POST',
url: 'https://api.foo.example.com/v1.0/trips/' + trip + '/operator',
data: {
operator_id: 6601
}
}).success(function() {
// It worked!
});
我以 GitHub API 身份验证为例,基本用法使用 curl -u "username" <api-endpoint-url>
。我不担心使用Authorization
HTTP 标头,因为此应用程序已经是仅 HTTPS,但在这种情况下,我不需要将密码存储在本地(例如 Web 存储或其他东西)吗?
我也读过这篇博文,我不确定这是否是我应该做的,如果是这样,我是否应该在该散列数据中包含用户名和密码?
也许我误解了 API 通常应该如何工作,如果是这样,有人澄清这一点会很棒!
我同意发送一些标头数据并将其存储在本地很奇怪,但是,相信,这就是方法。
您可以查看 HMAC 身份验证。
如今,许多 API 都使用它,或者对其进行调整以使用它。您将在标头中发送一些用户ID,与您的哈希连接。服务器将通过该阅读器识别用户。
您不需要在本地存储密码,只需在发出身份验证请求时服务器发送的哈希(或令牌)即可。
全部清除:
- 进行 API 调用以对用户进行身份验证
- 服务器将检查用户登录名/密码,如果一切正常,它将存储一个 TOKEN 并在请求时返回。
- 客户端存储令牌
- 所有后续请求都将在标头中发送该令牌
- 服务器将始终检查该令牌是否有效,并使用令牌或标头中发送的其他数据查找当前用户