1.需要优化的模块
- 1.使用redis存储验证码
- 验证码需要频繁的访问与刷新,对性能的要求较高
- 验证码不需永久的保存,通常在很短的时间后就会失效
- 分布式部署时,存在session共享的问题
- 2.使用redis存储登录凭证
- 每次处理请求时,都要查询用户的登录凭证,访问的频率非常高
- 3.使用redis缓存用户信息
- 处理每次请求时,都要根据凭证查询用户信息,访问的频率非常高
2.验证码优化
- 之前是将这个验证放入了session中,这样以后分布式部署也会有问题,所有我们用redis来存储,并将其设置为60s后过期。
- 编写获取key的方法
private static final String PREFIX_KAPTCHA = "kaptcha";
public static String getKaptchaKey(String owner){
return PREFIX_KAPTCHA + SPLIT + owner;
}
@RequestMapping(path = "/kaptcha", method = RequestMethod.GET)
public void getKaptcha(HttpServletResponse response){
String text = kaptchaProducer.createText();
BufferedImage image = kaptchaProducer.createImage(text);
String keptchaOwner = CommunityUtil.generateUUID();
Cookie cookie = new Cookie("keptchaOwner", keptchaOwner);
cookie.setMaxAge(60);
cookie.setPath(contextPath);
response.addCookie(cookie);
String rediskey = RedisKeyUtil.getKaptchaKey(keptchaOwner);
redisTemplate.opsForValue().set(rediskey, text, 60, TimeUnit.SECONDS);
response.setContentType("image/png");
try {
OutputStream os = response.getOutputStream();
ImageIO.write(image, "png", os);
} catch (IOException e) {
logger.error("响应验证码失败:" + e.getMessage());
}
}
@RequestMapping(path = "/login", method = RequestMethod.POST)
public String login(String username, String password, String code, boolean rememberme,
Model model, HttpServletResponse response,
@CookieValue("keptchaOwner") String keptchaOwner){
String keptcha = null;
if(StringUtils.isNotBlank(keptchaOwner)){
String redisKey = RedisKeyUtil.getKaptchaKey(keptchaOwner);
keptcha = (String) redisTemplate.opsForValue().get(redisKey);
}
if(StringUtils.isBlank(code) || StringUtils.isBlank(keptcha) || !(keptcha.equalsIgnoreCase(code))){
model.addAttribute("codeMsg", "验证码不正确!");
return "/site/login";
}
int expiredSeconds = rememberme ? REMEMBER_EXPIRED_SECONDS : DEFAULT_EXPIRED_SECONDS;
System.out.println(expiredSeconds);
Map<String, Object> map = userService.login(username, password, expiredSeconds);
if(map.containsKey("ticket")){
Cookie cookie = new Cookie("ticket", map.get("ticket").toString());
cookie.setPath(contextPath);
cookie.setMaxAge(expiredSeconds);
response.addCookie(cookie);
return "redirect:/index";
}else{
model.addAttribute("usernameMsg", map.get("usernameMsg"));
model.addAttribute("passwordMsg", map.get("passwordMsg"));
return "/site/login";
}
}
3.使用redis存储登录凭证
private static final String PREFIX_TICKET = "ticket";
public static String getTicketKey(String ticket){
return PREFIX_TICKET + SPLIT + ticket;
}
String redisKey = RedisKeyUtil.getTicketKey(loginTicket.getTicket());
redisTemplate.opsForValue().set(redisKey, loginTicket);
String redisKey = RedisKeyUtil.getTicketKey(ticket);
LoginTicket loginTicket = (LoginTicket) redisTemplate.opsForValue().get(redisKey);
loginTicket.setStatus(1);
redisTemplate.opsForValue().set(redisKey, loginTicket);
String redisKey = RedisKeyUtil.getTicketKey(ticket);
return (LoginTicket) redisTemplate.opsForValue().get(redisKey);
4.使用redis缓存用户信息
private static final String PREFIX_USER = "user";
public static String getUserKey(int userId){
return PREFIX_USER + SPLIT + userId;
}
User user = getCache(id);
if(user == null){
user = initCache(id);
}
return user;
userMapper.updateStatus(userId, 1);
clearCache(userId);
int rows = userMapper.updateHeader(userId, headerUrl);
clearCache(userId);
userMapper.updatePassword(id,password);
clearCache(id);