php 将 api 密钥传递给 rest api

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8567512/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 05:01:02  来源:igfitidea点击:

Passing api keys to rest api

phpcodeigniterrestapi-key

提问by MrFoh

Am working with phil sturgeon REST_Controller for codeigniter to create a REST api, so far i've been able to create a simple library for generating api keys for the users. My problem is now sending the api key to the API for each request, how i do this without having to manually send it for every request.

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

回答by zombat

You should look into request signing. A great example is Amazon's S3 REST API.

您应该研究请求签名。一个很好的例子是亚马逊的 S3 REST API

The overview is actually pretty straightforward. The user has two important pieces of information to use your API, a public user id and a private API Key. They send the public id with the request, and use the private key to sign the request. The receiving server looks up the user's key and decides if the signed request is valid. The flow is something like this:

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

  1. User joins your service and gets a user id (e.g. 123) and an API key.
  2. User wants to make a request to your API service to update their email address, so they need to send a request to your API, perhaps to /user/[email protected].
  3. In order to make it possible to verify the request, the user adds the user id and a signatureto the call, so the call becomes /user/[email protected]&userid=123&sig=some_generated_string
  4. The server receives the call, sees that it's from userid=123, and looks up the API key for that user. It then replicates the steps to create the signature from the data, and if the signature matches, the request is valid.
  1. 用户加入您的服务并获得用户 ID(例如 123)和 API 密钥。
  2. 用户想要向您的 API 服务发出请求以更新其电子邮件地址,因此他们需要向您的 API 发送请求,可能发送到 /user/[email protected].
  3. 为了可以验证请求,用户在调用中添加了用户id和签名,这样调用就变成了 /user/[email protected]&userid=123&sig=some_generated_string
  4. 服务器收到调用,发现它来自 userid=123,并查找该用户的 API 密钥。然后它复制从数据创建签名的步骤,如果签名匹配,则请求有效。

This methodology ensures the API key is never sent as part of the communication.

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

Take a look at PHP's hash_hmac()function, it's popular for sending signed requests. Generally you get the user to do something like put all the parameters into an array, sort alphabetically, concatenate into a string and then hash_hmacthat string to get the sig. In this example you might do:

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

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

Then add that $sigonto the REST url as mentioned above.

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

回答by Martin Bean

The idea of REST is that it's stateless—so no sessions or anything. If you want to authenticate, then this is where keys come in, and keys must be passed for every request, and each request authenticates the user (as REST is stateless, did I mention that?).

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

There are various ways you can pass a key. You could pass it as a parameter (i.e. http://example.com/api/resource/id?key=api_key) or you can pass it as part of the HTTP headers. I've seen APIs that specify you send your username, and an API key as the password portion of the HTTP basic access authorization header.

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

An example request:

一个示例请求:

<?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);

Where martinbeanwould be my account username on your website, and 4eefab4111b2awould be my API key.

martinbean我在您网站上的帐户用户名和4eefab4111b2aAPI 密钥在哪里。