从Web应用程序中分离API时的身份验证

时间:2015-01-04 19:35:15

标签: php api rest authentication api-design

我目前正计划重组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']);
}

显然,这不是非常RESTful,因此努力将两者分开。这就是我提出的建议(仍在进行中):

// 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
}

这似乎是不必要的开销但that's what it looks like in this answer。我认为在重组后我应该从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 Authentication为例,基本用法使用curl -u "username" <api-endpoint-url>。我并不担心使用Authorization HTTP标头,因为此应用程序已经只是HTTPS,但在这种情况下我不需要将密码存储在本地(例如Web存储或其他东西)?

我还阅读this blog post,我不确定这是不是我应该做的事情,如果是的话,我应该包含用户名和密码在那个哈希的数据blob?

也许我误解了API应该如何在一般情况下工作,如果是这样的话,那么有人清除它会很棒!

1 个答案:

答案 0 :(得分:0)

我同意发送一些标题数据并将其存储在当地是很奇怪的,但是,相信,就是这样。

您可以查看HMAC authentication

今天许多API使用它,或者使其适应。您将在标头中发送一些用户ID,与您的散列连接。服务器将识别该读者的用户。

您无需存储密码localy,只需存储服务器在发出身份验证请求时发送的哈希(或令牌)。

全部清除:

  1. 进行API调用以验证用户身份
  2. 服务器将检查用户登录名/密码,如果一切正常,它将存储TOKEN并在请求时返回。
  3. 客户端存储令牌
  4. 所有后续请求都会在标题
  5. 中发送该标记
  6. 服务器将始终检查该令牌是否有效,并使用令牌或标题中发送的其他数据查找当前用户