第七章
7.1 安全优化
1、秒杀接口隐藏
/getPaht 为用户和商品生成秒杀接口,redis:key:userId_goodId,value:(生成一个uuid,为用户生成秒杀接口,下次秒杀请求需要使用)
/{path}/do_miaosha 传入一个path参数,@PathVariable注解从URL中获取参数,进行验证从redis get,equals则进行下一步。
7.2 数学公式验证码
2、数学公式验证码防刷
1.生成图形验证码
new bufferedImage()生成图像
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
写入数字表达式:
String verifyCode = generateVerifyCode(rdm);
g.setColor(new Color(0, 100, 0));
g.setFont(new Font("Candara", Font.BOLD, 24));
g.drawString(verifyCode, 8, 24);
g.dispose();
7.3 图片验证码
- ScriptEngine使用 在Java中获取执行Javascript代码的引擎,执行verifycode的数字计算表达式,计算结果以userid_goodId为key存到redis中
controller输出图像,首先获取response对象,ImageIo.write( )
BufferedImage image = miaoshaService.createVerifyCode(user, goodsId);
OutputStream out = response.getOutputStream();
ImageIO.write(image, "JPEG", out);
out.flush(); // 刷新
out.close(); // 关闭io
return null;
在/path接口接收参数验证码
7.4 接口限流
3、接口限流
redis存储某个用户对某个接口的访问次数,以uri_user.getId() 为key,设置过期时间,例如900秒,代码实现逻辑 get的值大于500 则请求非法。(900秒内只能访问500次)
-
利用拦截器:
1、自定义注解 @AccessLimit(seconds=5, maxCount=5, needLogin=true) 对需要限流的方法进行拦截
2、自定义拦截器 extends HandlerInterceptorAdapter 重写方法preHandle
3、利用Threadlocal获取session,即user对象。
修改代码,getUser放到拦截器里面实现,同时存到redis和Threadlocal中,
之前实现的ArgumentReslover直接在Threadlocal中获取拦截器已经存入ThreadLocal的User对象。render(response, codeMsg) 在response中添加json
response.setContentType("application/json;charset=UTF-8"); // 设置编码 否则出现乱码
OutputStream out = response.getOutputStream();
String str = JSON.toJSONString(Result.error(cm));
out.write(str.getBytes("UTF-8"));
out.flush();
out.close();
4、在config类中注册拦截器
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter{ // 配置类
@Autowired
UserArgumentResolver userArgumentResolver;
@Autowired
AccessInterceptor accessInterceptor;
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(userArgumentResolver); // 注册自定义参数填充器
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(accessInterceptor); // 注册拦截器
}
}