在工做中常常碰见项目对接,那么该如何写一个安全的接口供给对方调用呢???java
1.公共接口,任何人均可以访问调用
1.1.适合场景,公司后台整合广告管理,提供统一的接口返回给公司其余项目调用和邮件模板调用,这时候须要设计一个统一的接口,返回广告的内容。还有天气查询等场景。安全
@PostMapping("/syncInfo") public Result syncInfo(@RequestParam(name = "data")String data){ if(!StringUtils.isNotBlank(data)){ return new Result("失败!",false,HttpCode.STATUS_104); } InfoVo infoVo = JSONObject.parseObject(data,InfoVo.class); dealInfo(infoVo); return new Result("成功!",true, HttpCode.STATUS_200); }
2.接口参数加密
2.1.适合场景,公司内部两个项目组进行对接,为了防止接口被暴露和伪造访问,这个时候须要对参数进行加密处理,防止接口被其余外部人员调用,通常采用desc或者aes对称加密,约定好秘钥进行对接。app
@PostMapping("/syncInfo") public Result syncInfo(@RequestParam(name = "data")String data){ try { if(!StringUtils.isNotBlank(data)){ return new Result("失败!",false,HttpCode.STATUS_104); } DES des = new DES("秘钥".getBytes()); String j = des.decryptStr(data); logger.debug("解码前:" + data); logger.debug("解码后:" + j); InfoVo infoVo = JSONObject.parseObject(j,InfoVo.class); dealInfo(infoVo); return new Result("成功!",true, HttpCode.STATUS_200); }catch (Exception e){ e.printStackTrace(); if(!StringUtils.isNotBlank(data)){ return new Result("系统错误!",false,HttpCode.STATUS_105); } } }
3.接口时效性加密+接口参数加密
3.1.适合场景,内部接口加密过的数据连接被暴露,不断有相同数据对接口进行访问,这个适合须要对接口加入时间戳参数,设计失效时间解决这个问题。加密
@PostMapping("/syncInfo") public Result syncInfo(@RequestParam(name = "data")String data){ try { if(!StringUtils.isNotBlank(data)){ return new Result("失败!",false,HttpCode.STATUS_104); } DES des = new DES("秘钥".getBytes()); String j = des.decryptStr(data); logger.debug("解码前:" + data); logger.debug("解码后:" + j); InfoVo infoVo = JSONObject.parseObject(j,InfoVo.class); if(AddSecondes(infoVo.getTime(),20) < new Date().getTime()){ return new Result("接口失效!",false,HttpCode.STATUS_100); } dealInfo(infoVo); return new Result("成功!",true, HttpCode.STATUS_200); }catch (Exception e){ e.printStackTrace(); if(!StringUtils.isNotBlank(data)){ return new Result("系统错误!",false,HttpCode.STATUS_105); } } }
4.接口时效性+接口参数加密+不一样来源的私钥
4.1适合场景, 当接口秘钥被泄露时,咱们能够对不一样的数据来源设置不一样的私钥,这样即便接口秘钥被泄露,没有私钥,依然不能对接口进行操做,并且能够记录是哪一个项目的秘钥被泄露,快速定位出问题的来源,且不会影响其余项目调用。debug
@PostMapping("/syncInfo") public Result syncInfo(@RequestParam(name = "data")String data){ try { if(!StringUtils.isNotBlank(data)){ return new Result("失败!",false,HttpCode.STATUS_104); } DES des = new DES("基础秘钥".getBytes()); String j = des.decryptStr(data); logger.debug("解码前:" + data); logger.debug("解码后:" + j); InfoVo infoVo = JSONObject.parseObject(j,InfoVo.class); if(AddSecondes(infoVo.getTime(),20) < new Date().getTime()){ return new Result("接口失效!",false,HttpCode.STATUS_100); } String sign = getSignByFrom(Info.getFrom()); logger.debug("来源秘钥"+sign); String k = des.decryptStr(Info.getData); dealInfo(k); return new Result("成功!",true, HttpCode.STATUS_200); }catch (Exception e){ e.printStackTrace(); if(!StringUtils.isNotBlank(data)){ return new Result("系统错误!",false,HttpCode.STATUS_105); } } }