Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/codeigniter/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 将api键传递给rest api_Php_Codeigniter_Rest_Api Key - Fatal编程技术网

Php 将api键传递给rest api

Php 将api键传递给rest api,php,codeigniter,rest,api-key,Php,Codeigniter,Rest,Api Key,我正在与codeigniter的phil sturgeon REST_控制器一起创建REST api,到目前为止,我已经能够创建一个简单的库来为用户生成api密钥。 我现在的问题是为每个请求向api发送api密钥,我如何做到这一点而不必为每个请求手动发送它。REST的思想是它是无状态的,因此没有会话或任何东西。如果您想进行身份验证,那么这就是密钥的来源,每个请求都必须传递密钥,每个请求都对用户进行身份验证(因为REST是无状态的,我有提到过吗?) 传递密钥有多种方法。您可以将其作为参数(即)传递

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

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

传递密钥有多种方法。您可以将其作为参数(即)传递,也可以将其作为HTTP头的一部分传递。我见过一些API,它们指定您发送用户名,以及一个API密钥作为HTTP基本访问授权头的密码部分

请求示例:

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

您应该研究请求签名。一个很好的例子是

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

  • 用户加入您的服务并获得用户id(例如123)和API 钥匙
  • 用户希望向您的API服务发出更新其电子邮件地址的请求,因此他们需要向您的API发送请求,可能是
    /user/update?电子邮件=new@example.com
  • 为了能够验证请求,用户将用户id和签名添加到呼叫中,因此呼叫变为
    /user/update?电子邮件=new@example.com&userid=123&sig=some\u生成的\u字符串
  • 服务器接收调用,发现它来自userid=123,并查找该用户的API密钥。然后,它复制从数据创建签名的步骤,如果签名匹配,则 请求是有效的
  • 此方法可确保绝不将API密钥作为通信的一部分发送

    看看PHP的函数,它是发送签名请求的常用函数。通常,您会让用户做一些事情,比如将所有参数放入一个数组,按字母顺序排序,连接成一个字符串,然后
    hash_hmac
    该字符串以获得sig。在本例中,您可以执行以下操作:

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

    然后将
    $sig
    添加到上面提到的RESTURL上。

    这种方法很简单,但本质上是不安全的。有人可以很容易地嗅出你的API密钥并开始自己使用它。如果您希望API密钥是私有的,则不希望将其作为请求的一部分发送。适用于活动监视器:当他们的一位客户因为在星巴克使用开放式无线连接而第一次被劫持API密钥时,活动监视器会有很多解释。访问令牌是一种常见的方法,但API键不是。访问令牌过期了,所以如果一个令牌被泄露,安全漏洞就不会那么大。但是如果我有你的API密钥,我可以生成任意多的访问令牌。有一个很好的理由,所有这些服务给你一个“秘密”钥匙。。。这应该是个秘密。任何让您传递密钥的服务都是错误的。请注意,Campaign Monitor(自2017年起)正在使用HTTPS URL传递其API密钥,因此是安全的。2011年@zombat指出这样做是危险的,我不确定这是不是真的。我只是试图理解这一点,因为我正在尝试这样做…
    /user/update?email=new@example.com&userid=123&sig=some_-generated_-string
    现在不能有人劫持
    some_-generated_-string
    并发送它,就像它来自他们自己?(我肯定他们不能,但也许你可以告诉我为什么?@jasondavis-是的,有人可以嗅到这个特殊的请求,这是真的。但是,由于每个请求的签名都会不同,因此嗅探它们并没有什么好处。充其量,他们所能做的就是发送完全相同的请求!它们不能生成恶意请求,因为要生成恶意请求,您需要机密API密钥。如果他们试图篡改他们嗅探到的请求中的数据,比如将电子邮件更改为
    evil@example.com
    ,签名将不再匹配,REST服务器在尝试验证请求时会拒绝该请求。如果用户从javascript发出请求,从而向全世界公开其API密钥,那么这种方法不是不安全吗?有人可以查看源代码,获取API密钥,并使用相同的方法生成有效的请求以调用服务器。或者我遗漏了什么。@zombat(我不这么认为,但无论如何…)当用户填写html表单时,有没有一种方法可以做到这一点?当我说‘user’时,我指的是注册用户,而不是通过存储秘密api密钥的本地PHP文件发送请求的开发人员。“如果没有,我该怎么办?”僵尸巴里斯·乌萨克利问了一个很好的问题。如何在javascript web应用程序中隐藏API密钥?对于使用相同API的手机应用程序市场,如何为每个下载的手机应用程序创建一个私有API并让API知道它?