【商城秒杀项目】-- 秒杀接口地址隐藏
每次点击秒杀按钮的时候,才生成秒杀地址,秒杀地址不是写死的,而是从服务端获取,动态拼接而成的地址(HTTP协议是明文传输,前端是防不住恶意用户的攻击,所以安全校验要放在服务端,从而禁止掉这些恶意攻击),本篇博客记录如何进行秒杀接口地址隐藏进行安全优化
实现思路:
在进行秒杀之前,先去后端获取一个动态的秒杀地址path(由后端生成随机字符串作为path),然后将这个随机字符串返回给前端,前端将这个字符串拼接成新的URL(url : “/miaosha/” + path + “/do_miaosha”)作为秒杀地址,再发请求到后端开始秒杀
前端代码逻辑如下:
获取随机字符串的接口代码:
/**
* 获取秒杀的path,并且验证验证码的值是否正确
* 加入注解,实现拦截功能,进而实现限流功能
*/
@AccessLimit(seconds = 5, maxCount = 5, needLogin = true)
@RequestMapping(value = "/path", method = RequestMethod.GET)
@ResponseBody
public Result<String> getMiaoshaPath(MiaoshaUser user,
@RequestParam("goodsId") long goodsId,
@RequestParam(value = "verifyCode", defaultValue = "0") int verifyCode) {
if (user == null) {
return Result.error(CodeMsg.SESSION_ERROR);
}
boolean check = miaoshaService.checkVerifyCode(user, goodsId, verifyCode);
if (!check) {
return Result.error(CodeMsg.REQUEST_ILLEGAL);
}
String path = miaoshaService.createMiaoshaPath(user, goodsId);
return Result.success(path);
}
createMiaoshaPath方法代码(生成随机数并加密作为path,并且存入缓存(设置缓存过期时间60s),然后将这个随机字符串返回给前端):
/**
* 创建一个临时的秒杀地址
*/
public String createMiaoshaPath(MiaoshaUser user, long goodsId) {
if (user == null || goodsId <= 0) {
return null;
}
String str = MD5Util.md5(UUIDUtil.uuid() + "123456");
//将生成的随机字符串保存到redis
redisService.set(MiaoshaKey.getMiaoshaPath, "" + user.getId() + "_" + goodsId, str);
return str;
}
保存到redis里的path如下:
然后在秒杀之前对path进行验证:
checkPath方法代码(将前端传来的path与缓存中的path进行比较,如果一致,则可以进行下面的秒杀逻辑,否则,是非法请求):
/**
* 验证秒杀地址
* @param user
* @param goodsId
* @param path
* @return
*/
public boolean checkPath(MiaoshaUser user, long goodsId, String path) {
if (user == null || path == null) {
return false;
}
String pathOld = redisService.get(MiaoshaKey.getMiaoshaPath, "" + user.getId() + "_" + goodsId, String.class);
return path.equals(pathOld);
}
加上了秒杀接口地址隐藏之后可以防止恶意用户登陆之后,通过不断调用秒杀地址接口来骚扰服务器,所以要动态获取秒杀地址,只有真正点击秒杀按钮,才会根据用户id和商品id生成对应的秒杀接口地址
但是,这种情况仍然不能解决利用机器人频繁点击按钮的操作,为了降低点击按钮的次数,以及高并发下,防止多个用户在同一时间内,并发出大量请求,还需加入数学公式图形验证码以及接口防刷等优化技术
上一篇: Android基于位置的服务应用程序– GPS位置
下一篇: PHP 字符串截取,支持中文和其他编码