当前位置:   article > 正文

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

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)

独家面经总结,超级精彩

本人面试腾讯,阿里,百度等企业总结下来的面试经历,都是真实的,分享给大家!

image

image

image

image

Java面试准备

准确的说这里又分为两部分:

  1. Java刷题
  2. 算法刷题

Java刷题:此份文档详细记录了千道面试题与详解;

image

image

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

Java面试准备

准确的说这里又分为两部分:

  1. Java刷题
  2. 算法刷题

Java刷题:此份文档详细记录了千道面试题与详解;

[外链图片转存中…(img-ZYAsKt1s-1713810793774)]

[外链图片转存中…(img-mizEKOe9-1713810793774)]

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

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号