登陆信息

最简单的登陆方式就是将信息存在Session中

使用Ticket是一种进阶的登陆方式,可以有效的扩展到分布式当中,从而避免粘性Session问题。

Untitled

流程:

Controller Login POST

@PostMapping("/login")
public String login(String username, String password, String code, boolean rememberme,
                    Model model, HttpServletResponse response, HttpSession session) {
    // 对比验证码
    String kaptcha = (String) session.getAttribute("kaptcha");
    if(StringUtils.isBlank(kaptcha) || StringUtils.isBlank(code) || !kaptcha.equalsIgnoreCase(code)) {
        model.addAttribute("codeMsg", "验证码不正确");
        return "/site/login";
    }

    // 是否记住我
    int expiredSeconds =  rememberme ? REMEMBER_EXPIERD_SECONDS : DEFAULT_EXPIRED_SECONDS;
    Map<String, Object> map = userService.login(username, password, expiredSeconds);
    if(map.containsKey("ticket")) {
        Cookie cookie = new Cookie("ticket", map.get("ticket").toString() );
        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";
    }
}

Controller Logout GET

@GetMapping("/logout")
public String logout(@CookieValue("ticket") String ticket) {
    userService.logout(ticket);
    HostHolder.clear();
    System.out.println("HostHolder clear");
    System.out.println(HostHolder.getUser());
    return "/index";
}

拦截器

取Cookies的工具类

public class CookiesUtil {
    public static String getValue(HttpServletRequest request, String name) {
        if(request == null || name == null) {
            throw new IllegalArgumentException("参数为空");
        }
        Cookie[] cookies = request.getCookies();
        if(cookies != null) {
            for(Cookie cookie: cookies) {
                if(cookie.getName().equals(name)) {
                    return cookie.getValue();
                }
            }
        }
        return null;
    }
}

上下文对象

public class HostHolder {
    static private ThreadLocal<User> threadLocal = new ThreadLocal<>();
    public static void setUser(User user) {
        threadLocal.set(user);
    }
    public static User getUser() {
        return threadLocal.get();
    }
    public static void clear() {
        threadLocal.remove();
    }
}

写一个拦截器