php - 通过将用户的ID +时间加密为JSON来创建访问 token

标签 php api security encryption access-token

我正在制作一个API,但我是新手。我想到了创建访问令牌的想法。基本上,我们使用密钥加密JSON数据,将其转换为Base64并将其作为访问令牌返回。稍后,API会解密该访问令牌并可以使用ID。例如。:

login method
我们检查用户名/密码是否正确,如果正确,则从数据库中获取用户ID。然后,我们构造访问令牌,该令牌将在以后的API调用中使用,如下所示:


我们制作一个JSON字符串,例如{"user_id":609, "logintime":"1430428180"}
我们使用加密功能(例如these),并使用我们的加密密钥对该JSON字符串进行加密。
我们将加密的字符串转换为Base64,因此它是可读的,并将其作为访问令牌返回。


稍后,当用户执行操作时,我们可以使用此访问令牌来了解用户。例如。:

update user info method:我们发送需要更新的数据和访问令牌,这是我们之前获得的。然后我们:


Base64解码访问令牌。
使用我们的加密密钥解密。
解析JSON数据,我们知道用户的ID,因此我们可以轻松地更新数据库。另外,我们知道API调用是合法的,因为解密后的字符串是JSON,并且包含user_idlogintime字段。


这种方法好吗?

最佳答案

在这个答案中,我将重点放在API安全性上,我认为这是问题背后的真正问题(由OP对第一个答案的评论提示)。

API密钥的用途

在用户登录困难,不可能或其他不希望的情况下使用API​​密钥。 API密钥用于身份验证,这是API访问权限的“证明我是谁”部分。授权或“我被允许这样做”通常存储在服务器上。

有效的API访问标准

为了使您对请求有效感到满意,必须考虑几点。


该请求是否来自授权用户?
请求在传输过程中是否被篡改?


为了确保点1随着时间的推移而成立,API还应考虑到秘密密钥保持秘密。


该请求不会损害未来请求的有效性。


请注意,尽管API密钥通常以HTTP标头形式发送,但为简单起见,我将在示例中使用GET变量。

单键API

某些API设置为使用单个密钥进行访问。让我们使用CEgJu8G483u3作为示例密钥。

用户将发送类似的请求

GET /users?apiKey=CEgJu8G483u3 HTTP/1.1
Host: api.bigorg.com


如果API通过HTTP进行通信,这本质上是不安全的:


该密钥对于任何爱管闲事的第三方都是公开可读的(因此可用)。
第三方可以随意篡改请求的主体,并且服务器不知道。


因此,在通过HTTP的单密钥API身份验证中,违反了安全标准1-3。

如果您的单密钥API仅通过HTTPS进行通信,则1-3仍然有效,可以认为是安全的。

摘要或签名API

Google和Amazon使用此方法来访问其许多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令牌(您的解决方案)

您的解决方案几乎与JSON Web Tokens相同,因此我假装您正在使用该解决方案。

该解决方案通过HTTPS是安全的。 (请勿使用HTTPS)


请求来自有效用户=>他们知道令牌
该请求未被篡改=> HTTPS阻止第三者篡改请求
访问密钥仍然是秘密=> HTTPS阻止第三者读取您的访问密钥


如果您的API使用的是HTTP /纯文本,则可以将JSON Web令牌用作访问密钥,但是您还需要生成一个私有机密,并使用该私有机密向请求中添加签名。

请注意,如果您使用的是HTTP,我不确定如何将机密传输到客户端。也许通过蜗牛邮件或电子邮件?

结论

您的想法已经被非常聪明的人复制。恭喜你!这意味着这是一个好主意!

如果您使用HTTPS,则您的访问密钥解决方案是可靠的。

关于php - 通过将用户的ID +时间加密为JSON来创建访问 token ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29977955/

相关文章:

php - 如果结帐页面中有特定变化,则隐藏付款方式 | Woocommerce

api - Moodle 用户注册 API

django - 将 API 从 CodeIgniter 迁移到 Django 的最佳方法

c - 在命令行中隐藏密码字段

security - 如果提供商受信任,通过电子邮件地址识别 OpenID 用户是否安全?

php - 使用 Carbon 更改日期格式

php - setPage() 函数 : 0 上的页码错误

php - 为什么我从 MySQL 查询中得到重复项?

php - 使用 CURL 发送自定义 header

php - getmyfreetraffic redirect已经接管了我的网站