在工做中常常碰見項目對接,那麼該如何寫一個安全的接口供給對方調用呢???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); } } }