API接口的安全设计验证:ticket,签名,时间戳

本文讨论了在API接口开发中如何通过使用时间戳、Token和签名来确保数据安全,包括用户登录后的Token管理、签名生成和验证,以及通过拦截器实现的参数检查,防止恶意篡改和重复访问。

概述

与前端对接的API接口,如果被第三方抓包并进行恶意篡改参数,可能会导致数据泄露,甚至会被篡改数据,我主要围绕时间戳,token,签名三个部分来保证API接口的安全性

在这里插入图片描述

1.用户成功登陆站点后,服务器会返回一个token,用户的任何操作都必须带了这个参数,可以将这个参数直接放到header里。

2.客户端用需要发送的参数和token生成一个签名sign,作为参数一起发送给服务端,服务端在用同样的方法生成sign进行检查是否被篡改。

3.但这依然存在问题,可能会被进行恶意无限制访问,这时我们需要引入一个时间戳参数,如果超时即是无效的。

4.服务端需要对token,签名,时间戳进行验证,只有token有效,时间戳未超时,签名有效才能被放行。

开放接口

没有进行任何限制,简单粗暴的访问方式,这样的接口方式一般在开放的应用平台,查天气,查快递,只要你输入正确对应的参数调用,即可获取到自己需要的信息,我们可以任意修改参数值。

/*

  • Description: 开放的接口

  • @author huangweicheng

  • @date 2020/12/21

*/

@RestController

@RequestMapping(“/token”)

public class TokenSignController {

@Autowired

private TokenSignService tokenSignService;

@RequestMapping(value = “openDemo”,method = RequestMethod.GET)

public List openDemo(int personId){

return tokenSignService.getPersonList(personId);

}

}

Token认证获取

用户登录成功后,会获取一个ticket值,接下去任何接口的访问都需要这个参数。我们把它放置在redis内,有效期为10分钟,在ticket即将超时,无感知续命。延长使用时间,如果用户在一段时间内没进行任何操作,就需要重新登录系统。扩展:记一次token安全认证的实践

@RequestMapping(value = “login”,method = RequestMethod.POST)

public JSONObject login(@NotNull String username, @NotNull String password){

return tokenSignService.login(username,password);

}

登录操作,查看是否有这个用户,用户名和密码匹配即可成功登录。

/**

  • Description:验证登录,ticket成功后放置缓存中,

  • @param

  • @author huangweicheng

  • @date 2020/12/31

*/

public JSONObject login(String username,String password){

JSONObject result = new JSONObject();

PersonEntity personEntity = personDao.findByLoginName(username);

if (personEntity == null || (personEntity != null && !personEntity.getPassword().equals(password))){

result.put(“success”,false);

result.put(“ticket”,“”);

result.put(“code”,“999”);

result.put(“message”,“用户名和密码不匹配”);

return result;

}

if (personEntity.getLoginName().equals(username) && personEntity.getPassword().equals(password)){

String ticket = UUID.randomUUID().toString();

ticket = ticket.replace(“-”,“”);

redisTemplate.opsForValue().set(ticket,personEntity.getLoginName(),10L, TimeUnit.MINUTES);

result.put(“success”,true);

result.put(“ticket”,ticket);

result.put(“code”,200);

result.put(“message”,“登录成功”);

return result;

}

result.put(“success”,false);

result.put(“ticket”,“”);

result.put(“code”,“1000”);

result.put(“message”,“未知异常,请重试”);

return result;

}

Sign签名

把所有的参数拼接一起,在加入系统秘钥,进行MD5计算生成一个sign签名,防止参数被人恶意篡改,后台按同样的方法生成秘钥,进行签名对比。

/**

  • @param request

  • @return

*/

public static Boolean checkSign(HttpServletRequest request,String sign){

Boolean flag= false;

//检查sigin是否过期

Enumeration<?> pNames = request.getParameterNames();

Map<String, String> params = new HashMap<String, String>();

while (pNames.hasMoreElements()) {

String pName = (String) pNames.nextElement();

if(“sign”.equals(pName)) continue;

String pValue = (String)request.getParameter(pName);

params.put(pName, pValue);

}

System.out.println(“现在的sign–>>” + sign);

System.out.println(“验证的sign–>>” + getSign(params,secretKeyOfWxh));

if(sign.equals(getSign(params, secretKeyOfWxh))){

flag = true;

}

return flag;

}

重复访问

引入一个时间戳参数,保证接口仅在一分钟内有效,需要和客户端时间保持一致。

public static long getTimestamp(){

long timestampLong = System.currentTimeMillis();

long timestampsStr = timestampLong / 1000;

return timestampsStr;

}

需要跟当前服务器时间进行对比,如果超过一分钟,就拒绝本次请求,节省服务器查询数据的消耗

拦截器

每次请求都带有这三个参数,我们都需要进行验证,只有在三个参数都满足我们的要求,才允许数据返回或被操作。

public class LoginInterceptor implements HandlerInterceptor {

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

分享

1、算法大厂——字节跳动面试题

2、2000页互联网Java面试题大全

3、高阶必备,算法学习

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
、算法大厂——字节跳动面试题**

[外链图片转存中…(img-BUPlPIEs-1713063480516)]

2、2000页互联网Java面试题大全

[外链图片转存中…(img-tzdaoHdA-1713063480516)]

3、高阶必备,算法学习

[外链图片转存中…(img-sCJH2Y3q-1713063480516)]

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

<think>好的,用户问的是如何在API接口中正确使用时间戳。首先,我需要回忆一下之前提供的引用内容,尤其是关于时间戳的部分。引用3提到时间戳用于防止请求重复使用,确保请求的唯一性。同时,时间戳应该参与签名计算,比如用MD5或者其他加密算法生成sign,这样即使有人截获请求,没有secret也无法伪造。 接下来,要分步骤说明如何正确使用时间戳。首先,生成时间戳,格式通常是yyyyMMddHHmmss,比如202310011530。然后,时间戳要作为参数添加到请求中,并且参与签名的生成。这一步很重要,因为签名验证的时候服务器会重新计算签名,如果时间戳被篡改,签名就不匹配了。 然后,服务器端需要验证时间戳的有效性。比如检查时间戳是否在合理的时间范围内,比如前后5分钟,防止重放攻击。如果时间戳过期,就拒绝请求。同时,还要注意处理时区问题,确保客户端和服务器的时间同步,否则会出现时间不一致导致的验证失败。 另外,引用2提到ticket的机制,可能和时间戳结合使用,比如ticket的有效期是10分钟,时间戳可以辅助验证请求是否在有效期内。这样双重验证能提高安全性。 可能用户还想知道具体的实现步骤,比如在代码中如何生成时间戳,如何验证,以及如何处理时间同步的问题。还需要提到签名算法的选择,比如MD5、SHA或者RSA,确保安全性。 用户可能没有明确说出的需求是防止重放攻击和参数篡改,时间戳正是解决这些问题的一部分。因此,在回答中需要强调时间戳在整体安全机制中的作用,而不仅仅是单独使用时间戳。 最后,生成相关问题时,要考虑用户可能的后续问题,比如如何选择签名算法、处理时间同步、其他安全措施等。这样能帮助用户更全面地理解API接口安全设计。</think>### API接口时间戳的正确使用方法 在API接口安全设计中,时间戳主要用于**防止重放攻击**和**确保请求时效性**。以下是具体实现步骤及原理: --- #### 一、时间戳的核心作用 1. **唯一性验证**:通过时间窗口限制请求有效期,避免历史请求被重复利用[^3]。 2. **防篡改支持**:时间戳需参与签名(Sign)计算,与参数绑定增强安全性[^3]。 --- #### 二、实现步骤 1. **生成时间戳** - 客户端生成当前时间的标准化字符串,例如:`yyyyMMddHHmmss`格式(如`202310011530`表示2023年10月1日15:30)。 - 代码示例(Python): ```python import datetime timestamp = datetime.datetime.now().strftime("%Y%m%d%H%M%S") ``` 2. **加入请求参数** - 将时间戳作为必传参数添加到请求URL或Body中: ``` http://api.example.com/data?key=APP_KEY&timestamp=202310011530&sign=xxxx ``` 3. **参与签名计算** - 将时间戳与其他参数按规则拼接,使用密钥(Secret)生成签名(如MD5、SHA256): ```python import hashlib params = "key=APP_KEY&timestamp=202310011530&param1=value1" sign = hashlib.md5(f"{params}&secret=APP_SECRET".encode()).hexdigest() ``` - **注意**:Secret不参与传输,仅用于签名生成[^3]。 4. **服务端验证** - **时间有效性检查**:对比当前时间与请求时间戳,超出阈值(如5分钟)则拒绝。 ```python def validate_timestamp(request_ts): server_ts = datetime.datetime.now() request_time = datetime.datetime.strptime(request_ts, "%Y%m%d%H%M%S") return (server_ts - request_time).total_seconds() <= 300 # 5分钟有效期 ``` - **签名二次验证**:服务端用相同规则重新计算签名,与客户端传入的Sign对比[^3]。 --- #### 三、关键注意事项 1. **时间同步问题** - 强制要求客户端与服务器使用NTP协议同步时间,避免时区或时钟偏差导致验证失败。 2. **动态时间窗口** - 高安全场景可缩短时间窗口(如1分钟),但需平衡用户体验[^2]。 3. **结合Token机制** - 如引用[2]所述,可将时间戳与Token(ticket)绑定,实现双重验证: - Token有效期10分钟,时间戳用于单次请求时效控制[^2]。 --- #### 四、典型应用场景 - **支付接口**:防止订单重复提交。 - **数据查询**:避免参数被截取后重复调用。 - **敏感操作**(如密码修改):限制操作时效性。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值