胡律师:13306647218

如何保证数据接口安全《如何设计一个安全可靠的》

时间:2021-07-11 18:40:11

如何设计一个安全可靠的 API  接口?

作者|高加文

编辑|涂敏

制作人| csdn (ID: csdn news)

近年来,随着RESTful API的普及,使用HTTP头传输认证令牌似乎是合理的。RESTful API接口设计简化了系统架构,减少了耦合,允许所有模块独立改进。

但是在实际的REST API接口设计过程中,需要考虑如何让认证更加安全可靠,比如不被第三方恶意请求,保证传输过程中的数据安全,防止重复提交。这篇文章将一起谈论它。

如何设计一个安全可靠的 API  接口?

传统的Session 认证方式

首先,我们来谈谈一些传统的认证方法。众所周知,HTTP协议是一个无状态协议,这意味着如果用户向我们的应用程序提供用户名和密码进行用户身份验证,那么用户在发出下一个请求时将必须再次进行身份验证,因为我们无法知道是哪个用户发出的请求,所以为了让我们的应用程序识别是哪个用户发出的请求,我们只能在服务器中存储一个用户登录信息, 并且这个登录信息会在响应时传输到浏览器,告诉它保存为cookie,这样下次就可以发送到我们的应用程序,这样我们的应用程序就可以识别请求来自哪个用户,这就是传统的基于会话的身份验证。

而且这种方式有很多问题:

首先,占用资源,要求每个用户在通过认证后在服务器上做一个记录,以便于认证用户的下一个请求。一般来说,会话存储在内存中,但是随着认证用户的增加,服务器的成本会明显增加。

其次,扩展性差: 客户端进行身份验证后,服务器会制作身份验证记录。如果认证记录存储在内存中,则意味着用户必须在此服务器上请求下一个请求,才能获得授权资源。在一些分布式场景中,它会限制负载平衡器的容量和应用程序的可伸缩性。

基于cookie的用户身份认证方法第三,容易遭受攻击: 容易被拦截,用户容易受到跨站点请求伪造攻击。

如何设计一个安全可靠的 API  接口?

基于Token 的鉴权方式

由于会话认证存在诸多问题,基于令牌的认证应运而生,它不需要将用户的认证信息或会话信息保存在服务器上。这意味着基于令牌认证机制的应用不需要考虑用户登录哪个服务器,为应用扩展提供了便利。

基于令牌的身份验证的令牌工作流程如下:

首先,客户端通过用户名和密码请求相应的API接口

其次,服务器将验证用户的信息

第三,服务器将在通过身份验证后向客户端发送令牌

第四,客户端存储令牌并将令牌值附加到每个请求

第五,服务器验证令牌值并返回数据

这种方式的典型代表是JWT(Json web token),这是一种基于Json的开放标准(RFC 7519),用于在网络应用环境之间传递声明。这个令牌被设计得紧凑而安全,特别适合分布式站点的单点登录(SSO)场景。JWT声明一般用于在身份提供者和服务提供者之间传递经过认证的用户身份信息,从而从资源服务器获取资源。它还可以添加其他业务逻辑所需的一些附加声明信息。令牌也可以直接用于身份验证或加密。

它的特点如下:

小尺寸(一串字符串)。因此,传输速度快

传输方式多种多样。可以通过HTTP头(推荐)/URL/POST参数等方式传输

严谨的结构。它本身(在有效负载中)包含所有与用户相关的身份验证消息,例如用户可访问的路由、访问有效期和其他信息。服务器不需要连接到数据库来验证信息的有效性,有效负载支持应用程序定制

支持跨域身份验证,主要应用于单点登录

JWT通常由三部分组成:

标题信息(标题)

消息正文(有效负载)

签名

如下图所示:

//表头{ 'alg': 'HS256 ',' typ': 'JWT' }

//有效载荷{ //保留声明' iss': 'a.com ',' exp': '1d ',//公开声明' http://a.com': true,//私人声明' company': 'A ',' awesome': true }

//$签名HS256(Base64(标头) '.'Base64(有效负载,保密)

//jwtjwt=base64(表头)'.'base64(有效负载)'.'$ signature其工作流程如下:

首先,客户端通过发送HTTP请求向服务器发送账号密码,通常使用POST请求。服务器会检查账号和密码是否合法。如果它们一致,它将根据密钥生成一个令牌并返回它。客户端接收该令牌并将其保存在本地。之后,当需要访问受保护的路由或资源时,只要附加令牌(通常使用Header的Authorization属性)并将其发送到服务器,服务器就会检查令牌是否有效并做出响应。

服务器收到令牌后,将反转构建过程,对JWT的三个部分进行解码。在这一步中,可以得到符号和有效载荷的算法。结合服务器配置的secretKey,可以重新生成一个新的$Signature,可以和原来的$Signature进行比较,验证令牌是否有效,只有通过认证后才能使用有效载荷的数据。

如何设计一个安全可靠的 API  接口?

如何保证接口安全性

为了实现接口的安全性,我们可以做以下:

首先,我们需要在传输过程中使用HTTPS对数据进行加密,避免使用HTTP这种明文传输协议,防止数据直接暴露在公网上。在使用HTTPS时,我们必须确保安全可靠的加密方法和SSL协议。目前主流是TLS1.2和最新的TLS1.3,同时证书也要验证,因为即使是HTTPS协议,证书也是可以伪造的。

其次,通常会在界面设计中加入令牌、时间戳、符号等参数,不同的参数有各自不同的用途:

时间戳,即Timestamp,是客户端调用接口时传入的当前时间戳,时间戳的目的是防止DoS攻击。每次调用接口时,接口都会判断服务器当前系统时间与接口传来的时间戳的差异。如果差异超过某个设定时间,例如设定时间为3分钟,则请求将被拦截。如果在设定的超时范围内,DoS攻击无法阻止。时间戳机制只能减少DoS攻击的时间,缩短攻击时间。如果黑客修改了时间戳的值,可以通过签名机制进行处理。

Sign,即签名,通常用于参数签名,以防止参数被非法篡改。最常见的是修改金额等重要敏感参数。符号的值是将所有非空参数按升序排序,然后将令牌密钥时间戳nonce(随机数)缝合在一起,然后使用某种加密算法对其进行加密。这种方法的优点是被劫持后,参数值会被修改。然后继续调用接口。虽然参数值已经被修改,但是攻击者可以篡改参数值,因为他不知道如何计算符号,但是不能修改符号的值。在服务器调用接口之前,它会根据符号的规则重新计算符号的值,然后将其与接口传递的符号参数的值进行比较。如果相等,则表示参数值未被篡改;如果不相等,则表示参数被非法篡改,因此不会返回真实的响应信息。

此外,在设计接口时,应实现幂等运算。所谓幂等运算就是防止重复运算。我们可以将生成的签名和密钥保存到redis中,并设置一个超时时间,在到期后自动删除它们。如果存在重复值,则不会对其进行处理,从而防止重复提交并确保请求结果的一致性。

其使用过程如下:

接口调用方(客户端)向接口提供方(服务器)申请接口调用帐户。成功应用后,接口提供者会给接口调用方一个AppKey和一个APP Secret参数

当调用方申请App Key和App Secret生成请求时,对参数进行拼接和加密,例如通过HMAC-SHA256或MD5加密,然后将App Key和加密结果附加到请求中。Sign=加密(appId时间戳密钥)

服务收到请求后,根据App Key识别主叫方,对获取的参数进行解密,并比较时间,判断是否超时。然后,它从字典中查找相应的App Secret,将其与请求参数拼接,对其进行加密,并将其与请求中的签名进行比较。如果签名结果相同,则是合法请求。

以上是对API接口设计的一些建议,仅供参考。在实际应用中,可以增加主机、接口版本等一些常用参数进行验证,以保证接口的安全性。

如何设计一个安全可靠的 API  接口?

如何设计一个安全可靠的 API  接口?