api接口的安全设计:使用token+sign+时间戳

2023-10-03 23:46:55 浏览数 (1)

服务端以api的方式将数据响应给客户端是目前的趋势,可以用在前后端分离的架构中,前后端分离之后,前后端人员能够更加专注于自己板块的东西,也可以用在服务端与服务端相互调用中。

拿到接口后,客户端就可以通过api获取接口提供的数据,而返回的数据一般分为两种情况,xml和json,在这个过程中,服务器并不知道,请求的来源是什么,有可能是别人非法调用我们的接口来获取数据,因此我们的api接口就要使用安全验证。

一、使用token进行用户身份认证

用户身份认证的流程图如下:

20210124164442864.png20210124164442864.png

具体说明如下:

①、用户登录时,客户端请求接口,传入用户名和密码

②、服务端对用户身份进行验证。若验证失败,则返回错误结果;若验证通过,则生成一个随机不重复的token,并将其存储在redis中(假设我们以存在redis中为例,也可以存储在DB中,存储在哪里具体看自己即可),设置一个过期时间。其中,redis的key为token,value为验证通过后获得的用户信息。

③、用户身份校验通过后,后台服务将生成的token返回客户端。客户端请求后续其他接口时,需要带上这个token。服务端会统一拦截接口请求,进行Token有效性校验,并从中获取用户信息,供后续业务逻辑使用。

二、使用sign防止传入参数被篡改

为了防止中间人攻击(客户端发来的请求被第三方拦截篡改,或接口被不信任的第三方进行调用),引入参数的签名机制

具体步骤如下:

①、客户端和服务端约定一个加密算法(比如 md5加密 或 sha1加密 或 先md5加密后再sha1加密......等双方自行协商加密算法方式即可), 客户端发起请求时,将所有的非空参数按升序或降序拼接在一起,通过加密算法形成一个sign,并将其放在请求中一起传递给服务端。

②、服务端统一拦截接口请求,用接收到的非可空参数根据约定好的规则同样进行加密,和客户端传入的sign值进行比较。若一致则予以放行,提供接口对应的数据,若不一致则拒绝客户端的请求。

由于中间人不知道加密方法,也就不能伪造一个有效的sign。从而有效防止了中间人对请求参数的篡改或防止了其它不被我们信任的第三方调用接口。

2021012417375499.png2021012417375499.png

三、用时间戳防止暴力请求

sign机制可以防止参数被篡改,但无法防ddos攻击(第三方使用正确的参数,不停的请求服务器,使之无法正常提供服务)。因此,还需要引入时间戳机制。

具体的操作为:客户端在生成sign值时,除了使用所有的参数和token外,再加一个发起请求时的时间戳。即:

代码语言:txt复制
sign值来源 = 所有非空参数升序排序(或 降序排序) token timestamp

而服务端则需要根据当前时间和sign值的时间戳进行比较,差值超过一段时间则不予通过客户端的请求,直接给客户端响应某些错误提示等。

若要求不高,则客户端和服务端可以仅仅使用精确到秒或分钟的时间戳,据此形成sign值来校验有效性。这样可以使一秒或一分钟内的请求是有效的。

若要求较高,则还需要约定一个解密算法,使服务端可以从sign值中解析出发起请求的时间戳。

总结后的流程图如下:

123.png123.png

0 人点赞