介绍

  • cookie 的工具类
  • 用于基于 cookie 的单点登录

代码

  1. @Slf4j
  2. public class CookieUtil {
  3. /**
  4. * COOKIE 的父级域名,他的子孙域名都可以访问到
  5. * 比如 a.b.c.myWeb.com, 在这里 a.b.c.myWeb.com 和 b.c.myWeb.com 和 c.myWeb.com 都属于 myWeb.com 的子域名
  6. * 后面还有有 path 的说法
  7. * 简单想
  8. * DOMAIN 作用域从右到左越长越小,path 从左到右越长越小
  9. * 而作用域小的可以访问作用域大的,相同作用域也无法访问
  10. */
  11. private final static String COOKIE_DOMAIN = "myWeb.com";
  12. private final static String LOGIN_TOKEN_NAME = "myWeb_login_token";
  13. /**
  14. * <h2> 写token到cookie中 </h2>
  15. *
  16. * @param response {@link HttpServletRequest}
  17. * @param token 要写入的 token
  18. */
  19. public static void writeLoginToken(HttpServletResponse response, String token) {
  20. Cookie cookie = new Cookie(LOGIN_TOKEN_NAME, token);
  21. cookie.setDomain(COOKIE_DOMAIN);
  22. cookie.setPath("/");
  23. cookie.setHttpOnly(true);
  24. // 保存时间,如果不设置,仅在当前窗口有效
  25. // 单位秒,-1 表永久
  26. cookie.setMaxAge(60 * 60);
  27. log.info("write cookieName: {}, cookieValue: {}", cookie.getName(), cookie.getValue());
  28. response.addCookie(cookie);
  29. }
  30. /**
  31. * <h2>从 cookie 中获取 token</h2>
  32. *
  33. * @param request {@link HttpServletRequest}
  34. * @return
  35. */
  36. public static String readLoginToken(HttpServletRequest request) {
  37. Cookie[] cookies = request.getCookies();
  38. if (Objects.isNull(cookies)) {
  39. return null;
  40. }
  41. for (Cookie cookie : cookies) {
  42. if (Objects.nonNull(cookie.getName()) && cookie.getName().equals(LOGIN_TOKEN_NAME)) {
  43. log.info("get target cookie-> cookieName: {}, cookieValue: {}", cookie.getName(), cookie.getValue());
  44. return cookie.getValue();
  45. }
  46. }
  47. return null;
  48. }
  49. /**
  50. * <h2>如果存在 login cookie,删除该 cookie</h2>
  51. *
  52. * @param request {@link HttpServletRequest}
  53. * @param response {@link HttpServletResponse}
  54. */
  55. public static void delLoginToken(HttpServletRequest request, HttpServletResponse response) {
  56. Cookie[] cookies = request.getCookies();
  57. for (Cookie cookie : cookies) {
  58. if (Objects.nonNull(cookie.getName()) && cookie.getName().equals(LOGIN_TOKEN_NAME)) {
  59. cookie.setDomain(COOKIE_DOMAIN);
  60. cookie.setPath("/");
  61. // 设置为 0 表示删除 cookie
  62. cookie.setMaxAge(0);
  63. log.info("del cookie--> cookieName: {}, cookieValue: {}", cookie.getName(), cookie.getValue());
  64. response.addCookie(cookie);
  65. }
  66. }
  67. }
  68. }

基于 cookie + redis的单点登录介绍

  • 为啥要 cookie + redis ?

    • cookie 保存 token
    • redis 保存 token 对应的敏感信息

      步骤

  • 登录

    • 生产一个 token
    • CookieUtil#writeLoginToken() 将 token 写入 cookie 中
    • token: <想要保存的信息, 一般是用户信息> 或者其他保存到 redis 中
      • 过期时间一般少于 cookie
  • 使用
    • CookieUtil#readLoginToken() 拿到 token
    • 使用 token 就可以从 redis 中获取之前要保存的信息了
  • 删除
    • CookieUtil#delLoginToken() 删除掉有 token 的 cookie
    • 删除 redis 中 token 对应的信息

注意点

  • 要写一个 filter/interceptor
    • 比较下 cookie 和 缓存中对应 token 的过期时间
    • 每次要更新下 redis 中 token 的过期时间,直到 cookie 结束
  • 一些敏感地方,比如更新用户信息,就需要重新设置 redis 中的消息了