手把手教你设计一个安全的对外接口

安全措施

数据加密、数据加签、时间戳机制、AppId机制、限流机制、黑名单机制、数据合法性校验等等。
详细可看https://blog.csdn.net/fengzongfu/article/details/105267563

如何实现

一、提供接口方

1、设计签名(MD5)

/**
 *	MD5签名
 *	签名内容为:	appId={url}&appKey={appKey}&nonce={nonce}&url={url}
 */
public static String getSign(String url, String appId, String appKey, String nonce) throws Exception {
	StringBuilder builder = new StringBuilder();
	builder.append("appId=").append(appId)
			.append("&appKey=").append(appKey)
			.append("&nonce=").append(nonce)
			.append("&url=").append(url);
	String signature = DigestUtils.md5DigestAsHex((builder.toString()).getBytes("UTF-8"));
	if (StringUtils.isBlank(signature)) {
		throw new RuntimeException("签名失败");
	}
	return signature;
}

2、验证签名

public static void validateSign(HttpServletRequest request, String appId, String appKey, String nonce, String timestamp) throws Exception {
	String requestURL = request.getRequestURI();
	String signature = request.getHeader("signature");
	if (StringUtils.isNoneBlank(signature) || StringUtils.isNoneBlank(appId) || StringUtils.isNoneBlank(appKey) ||
			StringUtils.isNoneBlank(nonce) || StringUtils.isNoneBlank(timestamp)) {
		throw new RuntimeException("数字签名校验错误");
	}

	long interval=1*1*60;//超时时间
	long serverTime=System.currentTimeMillis()/1000;
	long times = Long.parseLong(timestamp);
	if(times<interval+serverTime && times>serverTime-interval){
		throw new RuntimeException("数字签名校验错误");
	}

	String sign = getSign(requestURL, appId, appKey, nonce);

	if (StringUtils.isBlank(sign)) {
		throw new RuntimeException("数字签名校验错误");
	}

	if (!signature.equals(sign)) {
		throw new RuntimeException("数字签名校验错误");
	}
}

3、编写接口

@PostMapping(value = "/order/add?appid={appId}&nonce={nonce}&timestamp={timestamp}", produces = "application/json; charset=utf-8")
@ResponseBody
public ResponseObject addOrder(
	HttpServletRequest request,
	@PathVariable(value = "appId") String appId,
	@PathVariable(value = "nonce") String nonce,
	@PathVariable(value = "timestamp")String timestamp
	//body参数...
) {
	try {
	    SecurityUtils.validateSign(request,appId,appKey,nonce,timestamp);
	    //DO SOMETHING...
	    return ResponseObject.success();
	} catch (Exception e) {
	    logger.error("接口异常", e);
	    return ResponseObject.error(ResponseObject.ResponseCode_COMMON_ERROE, e.getMessage());
	}
}
二、使用接口方

同样使用上面的1获得签名
请求方法:

curl  '/order/add?appid={appId}&nonce={nonce}&timestamp={timestamp}'
-X POST
-H 'Content-Type: application/json,signature:{signature}'//signature为签名
-d '{
	"xxx": "xxx",//参数body
    "xxx": "xxxx"
}'
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值