通过将用户的id +时间加密为JSON来创建访问令牌

Gin*_*as_ 2 php security api encryption access-token

我正在制作API而且我是新手.我想到了创建访问令牌的想法.基本上,我们使用密钥加密JSON数据,将其转换为Base64并将其作为访问令牌返回.之后,API解密访问令牌并可以使用id.例如:

login method:我们检查用户名/密码是否正确,如果是,那么我们从数据库中获取用户的id.然后我们构造访问令牌,它将在未来的API调用中使用,如下所示:

  1. 我们制作一个JSON字符串,例如 {"user_id":609, "logintime":"1430428180"}
  2. 我们使用加密函数(例如这些)并使用我们的加密密钥加密该JSON字符串.
  3. 我们将加密的字符串转换为Base64,因此它是可读的并将其作为访问令牌返回.

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

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

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

这种做法有什么好处吗?

Jos*_*lik 10

在这个答案中,我将更多地关注API安全性,我认为这是问题背后的真正问题(由OP评论我的第一个答案提示).

API密钥的目的

API密钥用于用户登录困难,不可能或不合需要的情况.API密钥用于身份验证,"我是谁"的证明是API访问的一部分.授权或"我被允许这样做"通常存储在服务器上.

有效API访问的标准

为了让您满意请求有效,您必须考虑几个要点.

  1. 请求是否来自授权用户?
  2. 请求是否已在运输途中被篡改?

为了确保第1点持有一段时间为true,API还应该关注的是密钥保持秘密.

  1. 此请求不会损害未来请求的有效性.

请注意,虽然API密钥通常作为HTTP头发送,但为了简单起见,我将在我的示例中使用GET变量.

单键API

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

用户会发送一个请求

GET /users?apiKey=CEgJu8G483u3 HTTP/1.1
Host: api.bigorg.com
Run Code Online (Sandbox Code Playgroud)

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

  1. 密钥可由任何爱管闲事的第三方公开阅读(因此可用).
  2. 第三方可以根据需要篡改请求的正文,并且服务器不知道.

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

如果您的单个密钥API 通过HTTPS进行通信,那么1 - 3仍然有效并且可以被认为是安全的.

摘要或签名API

Google和亚马逊使用此方法访问其许多API.

当服务器授予对其系统的访问权限时,会生成两个密钥,一个标识符和一个密钥.

ACCESS_IDENTIFIER = 'bill';
ACCESS_SECRET = 'U59g5LcBBZpw';
Run Code Online (Sandbox Code Playgroud)

一旦生成了两个密钥,客户端和服务器就会存储秘密的副本,而这个副本永远不会再次直接传输.

当在该系统下发出请求时,标识符随请求一起提供(注意,访问密钥可以像随机生成的字符串一样复杂,或者像尝试访问系统的用户的id一样简单.

就在客户端发送请求之前,生成请求的摘要,然后使用先前商定的秘密加密.生成签名的方法各不相同,但现在常见的是HMAC.

然后请求看起来像这样

     GET /users?identifier=bill&signature=JjU1j1fIH62KG7FCTdZGzK7J HTTP/1.1
     Host: api.bigorg.com
Run Code Online (Sandbox Code Playgroud)

本例中使用的随机伪签名

如果在生成签名时包含请求正文,您现在可以安全地进行身份验证.

请注意,收听HTTP流量仍然非常简单,因此未经授权的知识仍然是一个问题,但是收听方无法发送自己的请求或篡改您的请求.

如果请求被篡改,签名将变为无效,请求将被拒绝.

JSON Web令牌(您的解决方案)

您的解决方案几乎与JSON Web Tokens相同,所以我只是假装您正在使用它.

此解决方案通过HTTPS安全.(DO使用HTTPS)

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

如果您的API使用HTTP /纯文本,则可以使用JSON Web令牌作为访问密钥,但您还需要生成私有密钥并使用该秘密为请求添加签名.

请注意,如果您使用HTTP,我不确定如何将秘密传送给客户端.也许通过蜗牛邮件或电子邮件?

结论

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

只要您使用HTTPS,您的访问密钥解决方案就是可靠的.