29

我正在与 phil sturgeon REST_Controller 一起为 codeigniter 创建一个 REST api,到目前为止,我已经能够创建一个简单的库来为用户生成 api 密钥。我的问题现在是将每个请求的 api 密钥发送到 API,我如何做到这一点而不必为每个请求手动发送它。

4

2 回答 2

54

您应该查看请求签名。一个很好的例子是Amazon 的 S3 REST API

概述实际上非常简单。用户有两个重要的信息可以使用您的 API,一个公共用户 ID 和一个私有 API 密钥。他们将公共 ID 与请求一起发送,并使用私钥对请求进行签名。接收服务器查找用户的密钥并确定签名请求是否有效。流程是这样的:

  1. 用户加入您的服务并获得用户 ID(例如 123)和 API 密钥。
  2. 用户想要向您的 API 服务发出请求以更新他们的电子邮件地址,因此他们需要向您的 API 发送请求,也许是 /user/update?email=new@example.com.
  3. 为了能够验证请求,用户在调用中添加了用户id和签名,所以调用变成了 /user/update?email=new@example.com&userid=123&sig=some_generated_string
  4. 服务器接收到调用,发现它来自 userid=123,然后查找该用户的 API 密钥。然后,它复制从数据创建签名的步骤,如果签名匹配,则请求有效。

这种方法确保API 密钥永远不会作为通信的一部分发送

看看 PHP 的hash_hmac()函数,它在发送签名请求时很受欢迎。通常,您会让用户执行一些操作,例如将所有参数放入一个数组中,按字母顺序排序,连接成一个字符串,然后hash_hmac是该字符串以获取 sig。在此示例中,您可能会这样做:

$sig = hash_hmac("sha256",$params['email'].$params['userid'],$API_KEY)

然后$sig如上所述将其添加到 REST url。

于 2011-12-19T21:39:16.800 回答
6

REST 的理念是它是无状态的——所以没有会话或任何东西。如果您想进行身份验证,那么这就是密钥的来源,并且必须为每个请求传递密钥,并且每个请求都对用户进行身份验证(因为 REST 是无状态的,我提到过吗?)。

您可以通过多种方式传递密钥。您可以将其作为参数传递(即http://example.com/api/resource/id?key=api_key),也可以将其作为 HTTP 标头的一部分传递。我见过指定您发送用户名和 API 密钥作为 HTTP 基本访问授权标头的密码部分的 API。

一个示例请求:

<?php

$ch = curl_init();
curl_setopt_array($ch, array(
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_URL => 'http://example.com/api/resource/id',
    CURLOPT_USERPWD => 'martinbean:4eefab4111b2a'
));
$response = curl_exec($ch);

martinbean我在您网站上的帐户用户名在哪里,并且4eefab4111b2a将是我的 API 密钥。

于 2011-12-19T21:24:25.587 回答