概述了连接前端的API接口。如果被第三方抓包恶意篡改参数,甚至可能导致数据泄露被篡改。我主要围绕时间戳、token、签名三部分来保证API接口的安全1、用户成功登录站点后,服务器会返回一个token。用户的任何操作都要带上这个参数,可以直接放在header里面。2、客户端用需要发送的参数和token生成签名sign,作为参数发送给服务端,服务端用同样的方法生成sign,检查是否被篡改。3.但是还是有问题,可能会被无限制的恶意访问。这时候我们需要引入一个时间戳参数。超时则无效。4.服务器需要验证令牌、签名和时间戳。只有token有效,时间戳没有超时,签名有效,才能放行。开放式接口没有任何限制,访问方式简单粗暴,此类接口方式一般用于开放式应用平台,比如查天气,查快递,只要输入正确的对应参数调用即可得到你需要的信息,我们可以任意修改参数值。/**描述:开放接口*@authorhuangweicheng*@date2020/12/21*/@RestController@RequestMapping("/token")publicclassTokenSignController{@AutowiredprivateTokenSignServicetokenSignService;@RequestMapping(value="openDemo",method=RequestMethod.GET)publicListopenDemo(intpersonId){returntokenSignService.getPersonList(personId);}}Token认证获取到用户登录成功后,会获取一个ticket值,后续任何接口访问该参数都需要这个值。我们放在redis里面,有效期是10分钟。当ticket即将超时时,会继续无感知。为了延长使用时间,如果用户在一段时间内没有进行任何操作,则需要重新登录系统。扩展:记住token安全认证的做法@RequestMapping(value="login",method=RequestMethod.POST)publicJSONObjectlogin(@NotNullStringusername,@NotNullStringpassword){returntokenSignService.login(username,password);}登录操作,检查是否有该用户,用户名和密码匹配成功登录。/****Description:验证登录,ticket成功后放置存档中,*@param*@authorhuangweicheng*@date2020/12/31*/publicJSONObjectlogin(Stringusername,Stringpassword){JSONObjectresult=newJSONObject();PersonEntitypersonEntity=personDao.findByLoginName(用户名);if(personEntity==null||(personEntity!=null&&!personEntity.getPassword().equals(password))){result.put("成功",false);result.put("票","");结果.put("代码","999");result.put("message","用户名和密码不匹配");返回结果;}if(personEntity.getLoginName().equals(username)&&personEntity.getPassword().equals(password)){Stringticket=UUID.randomUUID().toString();ticket=ticket.replace("-","");redisTemplate.opsForValue().set(ticket,personEntity.getLoginName(),10L,TimeUnit.MINUTES);结果.put("成功",真的);result.put("票",票);result.put("代码",200);result.put("消息","登录成功");返回结果;}result.put("成功",false);result.put("票","");结果.put("代码","1000");result.put("消息","未知异常,请重试");returnresult;}signsignature将所有参数拼接在一起,加上系统秘钥,进行MD5计算生成sign签名,防止参数被恶意篡改。后台同理生成秘钥,用于签名比对/***@paramrequest*@return*/publicstaticBooleancheckSign(HttpServletRequestrequest,Stringsign){Booleanflag=false;//检查sigin是否过期Enumeration>pNames=request.getParameterNames();Mapparams=newHashMap();while(pNames.hasMoreElements()){StringpName=(String)pNames.nextElement();如果(“符号”。等于(pName))继续;StringpValue=(String)request.getParameter(pName);params.put(pName,pValue);}System.out.println("当前符号-->>"+sign);System.out.println("验证标志-->>"+getSign(params,secretKeyOfWxh));if(sign.equals(getSign(params,secretKeyOfWxh))){flag=true;}返回标志;一分钟内有效,需与客户端时间一致。publicstaticlonggetTimestamp(){longtimestampLong=System.currentTimeMillis();长时间戳Str=timestampLong/1000;返回时间戳Str;需要与当前服务器时间进行比较。如果超过一分钟,这个请求会被拒绝,保存服务器查询数据,消费拦截器的每个请求都有这三个参数,我们需要验证。只有三个参数满足我们的要求,才允许返回或操作数据。公共类LoginInterceptor实现HandlerInterceptor{@AutowiredprivateRedisTemplateredisTemplate;@OverridepublicbooleanpreHandle(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler)throwsIOException{JSONObjectjsonObject=newJSONObject();Stringticket=request.getParameter("ticket");Stringsign=request.getParameter("sign");字符串ts=request.getParameter("ts");if(StringUtils.isEmpty(ticket)||StringUtils.isEmpty(sign)||StringUtils.isEmpty(ts)){jsonObject.put("成功",false);jsonObject.put("message","argsisEmpty");jsonObject.put("代码","1001");PrintWriterprintWriter=response.getWriter();printWriter.write(jsonObject.toJSONString());返回假;}//如果redis存在于ticket中就认为是合法的请求if(redisTemplate.hasKey(ticket)){System.out.println(redisTemplate.opsForValue().getOperations().getExpire(ticket));字符串值=(String)redisTemplate.opsForValue().get(ticket);//判断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","超时连接服务器");jsonObject.put("代码","1002");PrintWriterprintWriter=response.getWriter();printWriter.write(jsonObject.toJSONString());返回假;}//验证签名if(!SignUtils.checkSign(request,sign)){jsonObject.put("成功",false);jsonObject.put("消息","签名无效");jsonObject.put("代码","1003");PrintWriterprintWriter=response.getWriter();printWriter.write(jsonObject.toJSONString());返回假;}返回真;}else{jsonObject.put("成功",false);jsonObject.put("message","ticketisinvalid,Relogin.");jsonObject.put("代码","1004");PrintWriterprintWriter=response.getWriter();printWriter.write(jsonObject.toJSONString());}返回假;}}先登录访问系统,获取合法票证生成合法签名验证,获取测试ts,访问openDemo,可以正常访问,也可以加密参数,把http换成https,不会扩容一个一个。演示代码https://github.com/hwc4110/sp...作者:易建天门cnblogs.com/dslx/p/14116294.html