在工作中經常遇見專案對接,那麼該如何寫一個安全的介面供給對方呼叫呢???
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對稱加密,約定好祕鑰進行對接。
@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適合場景, 當介面祕鑰被洩露時,我們可以對不同的資料來源設定不同的私鑰,這樣即使介面祕鑰被洩露,沒有私鑰,依然不能對介面進行操作,而且可以記錄是哪個專案的祕鑰被洩露,快速定位出問題的來源,且不會影響其他專案呼叫。
@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);
}
}
}