秒杀接口地址隐藏
每次点击秒杀按钮,才会生成秒杀地址,秒杀地址不是写死的,是从服务端获取,动态拼接而成的地址。(HTTP协议是明文传输,前端是防不住恶意用户的攻击,所以安全校验要放在服务端,从而禁止掉这些恶意攻击。)
实现思路:
在进行秒杀之前,去后端获取一个动态的秒杀地址path(服务端生成随机数作为path),在然后将这个随机数返回给前端,前端用这个path拼接在新的请求url(url : “/miaosha/” + path + “/do_miaosha”)上作为参数,再去发请求到后台开始我们的秒杀
- 改造前端秒杀按钮,在发起请求之前,先去获取秒杀地址:
<button class="btn btn-primary" type="button" id="buyButton" onclick="getMiaoshaPath()">立即秒杀</button>
-
发起请求/miaosha/getPath去后端获取一个动态的秒杀地址path,然后前端在用这个path拼接在url(url : “/miaosha/” + path + “/do_miaosha”)上作为参数,再去发请求到后台开始我们的秒杀
getMiaoshaPath和doMiaosha(path)代码:
//获取秒杀地址
function getMiaoshaPath() {
var goodsId = $("#goodsId").val();
$.ajax({
url : "/miaosha/getPath",
type : "GET",
data : {
goodsId : goodsId,
//vertifyCode:$("#vertifyCode").val()
},
success : function(data) {
if (data.code == 0) {
//获取秒杀地址
var path = data.data;
//拿到path之后,才去做我的秒杀逻辑,并且在方法传入秒杀地址
doMiaosha(path);
} else {
layer.msg(data.msg);
}
},
error : function() {
layer.msg("请求有误!");
}
});
}
function doMiaosha(path) {
//alert(path);
$.ajax({
url : "/miaosha/" + path + "/do_miaosha",
type : "POST",
data : {
goodsId : $("#goodsId").val()
},
success : function(data) {
if (data.code == 0) {
getMiaoshaResult($("#goodsId").val());
} else {
layer.msg(data.msg);
}
},
error : function() {
layer.msg("请求有误!");
}
});
}
- 服务端生成随机数作为path,并且存入缓存(设置缓存过期时间60s),然后将这个随机数返回给前端
/**
* 获取秒杀的path,并且验证验证码的值是否正确
*/
@RequestMapping(value ="/getPath")
@ResponseBody
public Result<String> getMiaoshaPath(HttpServletRequest request,Model model,MiaoshaUser user,
@RequestParam("goodsId") Long goodsId,
@RequestParam(value="vertifyCode",defaultValue="0") int vertifyCode) {
model.addAttribute("user", user);
//如果用户为空,则返回至登录页面
if(user==null){
return Result.error(CodeMsg.SESSION_ERROR);
}
//生成一个随机串
String path=miaoshaService.createMiaoshaPath(user,goodsId);
return Result.success(path);
}
注意:写入缓存,是后端接收到这个请求秒杀地址path参数,并且与缓存中的存的path比较,如果一致,进行秒杀逻辑,否则,非法请求。
createMiaoshaPath方法:
/**
* 生成一个秒杀path,写入缓存,并且,返回至前台
*/
public String createMiaoshaPath(MiaoshaUser user, Long goodsId) {
String str=MD5Util.md5(UUIDUtil.uuid()+"123456");
//将随机串保存在客户端,并且返回至客户端。
//String path=""+user.getId()+"_"+goodsId;
redisService.set(MiaoshaKey.getMiaoshaPath, ""+user.getId()+"_"+goodsId, str);
return str;
}
加上了秒杀接口地址隐藏之后可以防止恶意用户登陆之后,通过不断调用秒杀地址接口,骚扰服务器,所以使用动态获取秒杀地址,只有真正点击秒杀按钮,才会根据用户id和商品goodsId生成对应的秒杀接口地址。
但是,这种情况仍然不能解决利用机器人频繁点击按钮的操作,为了降低点击按钮的次数,以及高并发下,防止多个用户在同一时间内,并发出大量请求,加入数学公式图形验证码以及接口防刷等优化技术。