API 接口的安全性及鉴权方式

什么是 API 鉴权

公司、个人开发的系统上线后,系统中 API 暴露到互联网上会存在一定的安全风险,eg: 爬虫、恶意访问等。因此我们要先对接口调用方做一个用户鉴权,对访问 API 权限进行限制,如果鉴权通过则允许用户调用 API。根据不同的场景鉴权方案也有很多种。

常用 API 接口安全措施🔐

数据加密

数据在互联网传输过程很容易被抓包,如果直接传输,那么用户数据可能被其他人获取,导致系统安全性等问题,所以必须对数据加密。常见的做法是对关键字段加密,比如用户密码直接通过 md5 加密。

数据签名

数据在传输过程中经过加密,理论上就算被抓包,也无法对数据进行篡改,但是我们一般加密的部分其实只是在外网,现在很多服务在内网中都需要经过很多服务跳转,如果被攻入内网,则可以在任意节点篡改数据,所以这里的加数据签名可以防止内网中数据被篡改。数据签名就是由发送者产生一段无法伪造的一段数字串,来保证数据在传输过程中不被篡改。

md5算法是常用的数据签名算法,其原理是将需要提交的数据通过某种方式组合成一个字符串,然后通过md5算法生成一段加密字符串,这段加密字符串就是数据包的签名。为保证安全性,最后的密钥会在客户端和服务端各备一份。

添加时间戳

经过如上的加密,加签处理,就算拿到数据也不能看到真实的数据;但是有些攻击者不关心真实的数据,而是直接拿到抓取的数据包做恶意请求,以达到攻击的目的。我们可以使用时间戳机制,在每次请求的时候加入当前的时间,服务器端会拿到当前时间和消息中的时间相减,看看是否在一个固定的时间范围内,超过时间差的请求就视为非法请求。

限流机制

如果有用户出现频繁调用接口的情况;这种情况需要给相关用户做限流处理,常用的限流算法包括:令牌桶限流,漏桶限流,计数器限流。

  • 令牌桶限流:系统以一定速率向桶中放入令牌,填满了就丢弃令牌;请求来时会先从桶中取出令牌,如果能取到令牌,则可以继续完成请求,否则等待或者拒绝服务。令牌桶允许一定程度突发流量,只要有令牌就可以处理,支持一次拿多个令牌;
  • 漏桶限流:按照固定常量速率流出请求,流入请求速率任意,当请求数超过桶的容量时,新的请求等待或者拒绝服务,因此漏桶算法可以强制限制数据的传输速度;
  • 计数器限流:这是一种比较简单粗暴的算法,主要用来限制总并发数,比如数据库连接池、线程池、秒杀的并发数;计数器限流只要一定时间内的总请求数超过设定的阀值则进行限流。

黑名单限流

如果此用户进行过很多非法操作,或者说专门有一个中黑系统,经过分析之后直接将此用户列入黑名单,所有请求直接返回错误码。

我们可以给每个用户设置一个状态比如包括:初始化状态,正常状态,中黑状态,关闭状态等等;或者我们直接通过分布式配置中心,直接保存黑名单列表,每次检查是否在列表中即可。

常用 API 鉴权方式

数据在互联网中传输是不安全的,所有处于开放环境的数据传输都可以被截取、篡改,因此数据传输必须签名加密。

签名核心解决的以下问题:

  • 请求是否合法:请求数据的是否是我规定的那部分人
  • 请求是否被篡改:请求的数据是否是原始数据,是否被篡改过
  • 防止重复请求(防重放):是否重复请求

Cookie + Session 实现 API 鉴权

Cookie + Session 是最传统的 API 鉴权方式,比如很多网站的登录模块就是靠这种方式实现用户会话管理。在服务端会生成一个 session 来保持会话状态,各个 session 是通过唯一的 session_id 来标识,以次来判断请求是那个客户端发起的,session_id 存储在客户端的 cookie 中,后续所有的请求都会把 cookie 传到服务端,服务端解析 cookie 后找到对应的 session 进行判断。

特点:

  1. 为了使后台应用识别是那个用户发出的请求,需要在服务端存储一份用户登录信息(session),这份信息也会在相应前端请求时返回给客户端,客户端将其保存在 cookie
  2. 客户端下次请求时发送给服务端,服务端根据这个标识来识别具体时那个用户
  3. cookie 内仅包含一个 session 标识符,其他用户信息还是存储在服务端中

缺点:

  1. 性能相对较低:每一个用户经过服务端认证后服务端都要做一次记录,以方便下次请求的鉴别,通常 session 都是保存在内存中,而随着用户认证增多,服务端开销会越来越大
  2. 在一个无状态协议里注入状态,与 REST 风格不匹配
  3. 因为改方案是基于 cookie 来进行识别,cookie 如果被获取用户很容易受到 CSRF 攻击
  4. 很难跨平台,在移动端应用 sessioncookie 很难行通,你无法与移动终端共享服务端创建的 sessioncookie

API Key + API Secret

这种方式是指当请求的资源、API KeyAPI Secret 匹配时,用户才可以访问对应的资源,一般还会加上时间戳等方式来进行请求的时效控制。

实现方法:

  1. 服务器生成一对 Key/Secret 保存,并下发给客户端,KeySecret 均是按照某种规则随你生成,互相无法推算
  2. 在客户端发起请求时,需要将包含 API Key 在内的所有请求参数排序(一般都是使用字典序),然后跟 API Secret(相当于加盐)一起做 hash 生成一个 sign 参数,服务器只需要按照约定的规则做一次签名计算,然后和请求的签名做比较,如果一致则验证通过,如果验证不通过则拒绝

这种模式并不是RBAC(角色权限控制),而是 ACL(Access Control List: 访问控制列表) 访问控制。这种方式实现简单,占用的计算资源和网络资源都较少,安全性也可以。但是一般来说每一个 api 都需要分配一对 KeySecret,因此当 KeySecret 比较多的时候,服务器会有一定的存储成本,而且服务端只能通过 API Key 来区别调用者,API Secret 一旦泄露将造成较大的安全风险。这种模式一般适用于 Web API

有时为了避免重放攻击,会加上时间戳参数,服务单验证时如果时间超过允许范围则验证失败。

注意:加时间戳这种方式一般是在和地方系统对接中使用,一般客户端访问不要求携带时间戳,因为客户端获取的时间是用户电脑的时间,可能不准确导致无法和服务的的时间保持一致。

token 机制实现 API 鉴权

token 令牌机制是用来代替 session 的鉴权方式,token 机制是服务端根据特定的规则生成的一串加密字符串下发给客户端,客户端请求服务端所有资源时都会携带上这个 Token(一般设置在 header 中)。服务端来校验这个 token 的合法性,这种方式具有无状态、适合分布式、扩展性好、性能和安全性好更好等优点

image-20220116102112848

常见 Token 实现有以下几种:

  • 自定义实现 token:应用开发者根据 token 机制原理自行实现
  • JWT:即 json web token,是一种主流的 token 规范
  • Oauth:Oauth 虽然时授权规范,但其中也用到 TOken
  • HTTP Basic Authentication 认证机制
  • Web API 是基于 HTTP 协议,而 HTTP 协议本身就带有认证机制

第三方系统对接鉴权(重放攻击)

虽然上方的鉴权方式可以屏蔽大部分非法请求,可事实上,如果仿冒者监听并截取到了请求片段,然后把签名单独截取出来模仿正式请求方欺骗服务器进行重复请求,这也会造成安全问题,这攻击方式就叫重放攻击(replay 攻击)。这种方式我们就可以通过加入 timestamp + nonce 两个参数来控制请求有效性,防止重放攻击。

  • timestamp

客户端:timestamp 由客户端生成,标识请求时间(客户端需要先检验是否和服务端时间是否一致,且双方使用统一时区计数系统)随请求一并发出,并将 timestamp 作为一个参数加入 sign 加密计算

服务端:服务端接收到请求后对比系统当前时间,设定不超过某个时间段即认为请求正常,反之则为非法请求,但这还不够,仿冒者仍然可以在这个规定的时间段内模拟请求进行重放攻击。所以更近一步可以为 sign 加上一个随机码(盐值),我们这里定义为 nonce

  • nonce

请求端:nonce 是由请求方生成的随机数(在规定时间内保证有充足的随机数产生,且重复率为0)也作为参数之一加入 sign 签名

服务端:服务器接受到请求先判定 nonce 是否被请求过(一般会放到redis中),如果发现 nonce 参数在规定时间是全新的则正常返回结果,反之,则判定是重放攻击。而由于以上2个参数也写入了签名当中,攻击方刻意增加或伪造 timestampnonce 企图逃过重放判定都会导致签名不通过而失败。

签名过程实例:

// 拼接待签名字符串
StringToSign = URL + "\n" +
        Query + "\n" +
        Content-MD5 + "\n" +
        Timestamp + "\n" +
        nonce

// 计算签名
Sign = Base64(HMAC-SHA256(ClientSecret, UTF-8-Encofing-of(stringToSign)));
  • URL: 指所访问的资源路径,如 /api/users/1
  • Query: 指请求中的 Query 参数,对参数 key 进行字典序升序排序,所有参数以 key=value 方式拼接,如 age=12&name=alex,若无此参数则设为空字符串
  • Content-MD5: body 数据的 md5sum,采用大写字符串,若无此参数则设为空字符串
  • ClientSecret:密匙
  • 3
    点赞
  • 79
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 对于您的问题,我可以回答。在Magic-api中,您可以通过添加接口鉴权来提高接口安全性。您可以使用API密钥、JWT Token等方式进行接口鉴权,以确保只有授权用户才能访问接口。在具体实现上,您可以在请求头中添加相应的授权信息,并在服务端对该信息进行验证,以确定用户是否有访问该接口的权限。 ### 回答2: 鉴权是用于验证API请求是否合法的一种安全措施。在使用magic-api添加接口鉴权时,可以采用以下步骤: 1. 生成密钥:首先,需要生成一个用于鉴权的密钥。可以使用常见的加密算法如HMAC-SHA256等来生成密钥。确保密钥具有足够的复杂度和安全性。 2. 将密钥配置到magic-api:在magic-api的配置文件中,添加一个鉴权相关的配置项,将生成的密钥配置到该项中。这个配置项可以是一个字符串,也可以是一个文件路径,存储密钥的值。 3. 添加鉴权中间件:在接口请求处理流程中,添加一个鉴权中间件。该中间件的作用是在请求到达API处理逻辑之前,对请求进行鉴权验证。通过读取配置的密钥,对请求的参数、头部信息等进行加密或签名,并与鉴权中间件请求中的加密或签名进行比对。 4. 验证鉴权结果:鉴权中间件会返回一个鉴权结果,通常可以是布尔值或者一个带有鉴权信息的对象。根据鉴权结果,可以决定是否允许继续处理该请求。如果鉴权失败,返回一个相应的错误信息,并拒绝该请求。 5. 日志记录:为了追踪和审计API请求的鉴权情况,可以在鉴权中间件中添加日志记录的功能。记录每个请求的鉴权结果、鉴权时间、请求参数等信息,以便后续的统计和分析。 通过以上步骤,可以在magic-api中添加接口鉴权功能,提高API安全性和可靠性,确保只有经过合法鉴权的请求能够被正常处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值