我正在制作API而我是新手。我想到了创建访问令牌的想法。基本上,我们使用密钥加密JSON数据,将其转换为Base64并将其作为访问令牌返回。之后,API解密访问令牌并可以使用id。 E.g:
login method
:
我们检查用户名/密码是否正确,如果是,那么我们从数据库中获取用户的id。然后我们构造访问令牌,它将在未来的API调用中使用,如下所示:
{"user_id":609, "logintime":"1430428180"}
稍后,当用户执行操作时,我们可以使用此访问令牌来了解用户。 E.g:
update user info method
:我们发送的数据需要更新,并且我们之前获得了访问令牌。然后我们:
user_id
和logintime
字段。这种做法有什么好处吗?
答案 0 :(得分:10)
在这个答案中,我将更多地关注API安全性,我认为这是问题背后的真正问题(OP对我的第一个答案的评论提示)。
API密钥用于登录用户困难,不可能或不合需要的情况。 API密钥用于身份验证,"证明我是谁" API访问的一部分。 授权,或者"我被允许这样做"通常存储在服务器上。
为了让您对请求有效感到满意,您必须考虑几点。
为了确保第1点在一段时间内保持为真,API也应该担心密钥保持机密。
请注意,尽管API密钥通常作为HTTP标头发送,但为了简单起见,我将在我的示例中使用GET变量。
某些API设置为使用单个密钥进行访问。我们使用CEgJu8G483u3
作为示例键。
用户将通过
之类的请求发送GET /users?apiKey=CEgJu8G483u3 HTTP/1.1
Host: api.bigorg.com
如果API通过HTTP进行通信,则固有不安全:
因此,在通过HTTP进行单键API身份验证时,违反了安全标准1 - 3。
如果您的单一密钥API通过HTTPS 进行通信,那么1 - 3仍然有效并且可以被认为是安全的。
Google和亚马逊使用此方法访问其许多API。
当服务器授予对其系统的访问权限时,会生成两个键,标识符和密码。
ACCESS_IDENTIFIER = 'bill';
ACCESS_SECRET = 'U59g5LcBBZpw';
一旦生成了两个密钥,客户端和服务器就会存储秘密的副本,而这个密钥永远不会再被直接传输。
在此系统下发出请求时,标识符随请求一起提供(请注意,访问密钥可能与随机生成的字符串一样复杂,或者与尝试访问系统的用户的ID一样简单。
在客户端发送请求之前,生成请求的摘要,然后使用先前商定的秘密加密。生成签名的方法各不相同,但现在常见的方法是HMAC。
请求看起来像这样
GET /users?identifier=bill&signature=JjU1j1fIH62KG7FCTdZGzK7J HTTP/1.1
Host: api.bigorg.com
此示例中使用的随机伪签名
如果在生成签名时包含请求正文,您现在可以安全地进行身份验证。
请注意,收听HTTP流量仍然非常简单,因此未经授权的知识仍然存在问题,但是收听方无法发送自己的请求或篡改您的请求。
如果请求被篡改,签名将失效,请求将被拒绝。
您的解决方案几乎与JSON Web Tokens完全相同,因此我只是假装您正在使用它。
此解决方案通过HTTPS安全。 ( DO 使用HTTPS)
如果您的API使用HTTP /纯文本,您可以使用您的JSON Web代币作为访问密钥,但您还需要生成私有密钥并使用它来为请求添加签名。
请注意,如果您正在使用HTTP,我不确定您将如何将密码传输到客户端。也许通过蜗牛邮件或电子邮件?
你的想法被非常聪明的人所复制。恭喜!这意味着这是一个好主意!
只要您使用HTTPS,您的访问密钥解决方案就是可靠的。
答案 1 :(得分:0)
在进行身份验证,访问令牌,您拥有什么时,您通常会更好地使用经过验证的图书馆,这个图书馆的人比我们两个人都聪明得多。
创建Json Web Tokens或JWT是为了解决这类问题(以及其他问题)。它has a PHP library。
因此,为用户创建访问令牌将如下所示。 (解释自述)
<?php
$key = "my-secret-key-here";
$token = array(
"user_id": 1
);
$jwt = JWT::encode($token, $key);
/**
* $jwt is your JSON web token, it will look something like this:
*
* eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiMSJ9.TcXz_IwlmxO5nPd3m0Yo67WyYptabkqZW4R9HNwPmKE
*
**/
$decoded = JWT::decode($jwt, $key, array('HS256'));
print_r($decoded);
/*
NOTE: This will now be an object instead of an associative array. To get
an associative array, you will need to cast it as such:
*/
$decoded_array = (array) $decoded;
?>
因此,在回答您的问题时,您已走上正轨! JWT似乎完全按照您在此处描述的内容进行操作,因此我选择了经过更全面测试的库的安全性。