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

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 {

@Autowired

private RedisTemplate redisTemplate;

@Override

public boolean preHandle(HttpServletRequest request, HttpServletResponse response,Object handler) throws IOException {

JSONObject jsonObject = new JSONObject();

String ticket = request.getParameter(“ticket”);

String sign = request.getParameter(“sign”);

String ts = request.getParameter(“ts”);

if (StringUtils.isEmpty(ticket) || StringUtils.isEmpty(sign) || StringUtils.isEmpty(ts)){

jsonObject.put(“success”,false);

jsonObject.put(“message”,“args is isEmpty”);

jsonObject.put(“code”,“1001”);

PrintWriter printWriter = response.getWriter();

printWriter.write(jsonObject.toJSONString());

return false;

}

//如果redis存在ticket就认为是合法的请求

if (redisTemplate.hasKey(ticket)){

System.out.println(redisTemplate.opsForValue().getOperations().getExpire(ticket));

String values = (String) redisTemplate.opsForValue().get(ticket);

//判断ticket是否即将过期,进行续命操作

if (redisTemplate.opsForValue().getOperations().getExpire(ticket) != -2 && redisTemplate.opsForValue().getOperations().getExpire(ticket) < 20){

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

}

System.out.println(SignUtils.getTimestamp());

//判断是否重复访问,存在重放攻击的时间窗口期

if (SignUtils.getTimestamp() - Long.valueOf(ts) > 600){

jsonObject.put(“success”,false);

jsonObject.put(“message”,“Overtime to connect to server”);

jsonObject.put(“code”,“1002”);

PrintWriter printWriter = response.getWriter();

printWriter.write(jsonObject.toJSONString());

return false;

}

//验证签名

if (!SignUtils.checkSign(request,sign)){

jsonObject.put(“success”,false);

jsonObject.put(“message”,“sign is invalid”);

jsonObject.put(“code”,“1003”);

PrintWriter printWriter = response.getWriter();

printWriter.write(jsonObject.toJSONString());

return false;

}

return true;

}else {

jsonObject.put(“success”,false);

jsonObject.put(“message”,“ticket is invalid,Relogin.”);

jsonObject.put(“code”,“1004”);

PrintWriter printWriter = response.getWriter();

printWriter.write(jsonObject.toJSONString());

}

return false;

}

}

访问

先登录系统,获取合法的ticket

在这里插入图片描述

生成一个合法的sign验证,获取测试ts,访问openDemo,即可正常访问。还可以将参数加密,将http换成https,就不一 一展开了。

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

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

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

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

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

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

img

如何快速更新自己的技术积累?

  • 在现有的项目里,深挖技术,比如用到netty可以把相关底层代码和要点都看起来。
  • 如果不知道目前的努力方向,就看自己的领导或公司里技术强的人在学什么。
  • 知道努力方向后不知道该怎么学,就到处去找相关资料然后练习。
  • 学习以后不知道有没有学成,则可以通过面试去检验。

我个人觉得面试也像是一场全新的征程,失败和胜利都是平常之事。所以,劝各位不要因为面试失败而灰心、丧失斗志。也不要因为面试通过而沾沾自喜,等待你的将是更美好的未来,继续加油!

以上面试专题的答小编案整理成面试文档了,文档里有答案详解,以及其他一些大厂面试题目

八年CRUD,疫情备战三个月,三面头条、四面阿里拿offer面经分享

八年CRUD,疫情备战三个月,三面头条、四面阿里拿offer面经分享

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
以,劝各位不要因为面试失败而灰心、丧失斗志。也不要因为面试通过而沾沾自喜,等待你的将是更美好的未来,继续加油!**

以上面试专题的答小编案整理成面试文档了,文档里有答案详解,以及其他一些大厂面试题目

[外链图片转存中…(img-obJqTBhN-1713306783307)]

[外链图片转存中…(img-yOCMuO4C-1713306783308)]

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

  • 26
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值