介绍
- cookie 的工具类
- 用于基于 cookie 的单点登录
代码
@Slf4j
public class CookieUtil {
/**
* COOKIE 的父级域名,他的子孙域名都可以访问到
* 比如 a.b.c.myWeb.com, 在这里 a.b.c.myWeb.com 和 b.c.myWeb.com 和 c.myWeb.com 都属于 myWeb.com 的子域名
* 后面还有有 path 的说法
* 简单想
* DOMAIN 作用域从右到左越长越小,path 从左到右越长越小
* 而作用域小的可以访问作用域大的,相同作用域也无法访问
*/
private final static String COOKIE_DOMAIN = "myWeb.com";
private final static String LOGIN_TOKEN_NAME = "myWeb_login_token";
/**
* <h2> 写token到cookie中 </h2>
*
* @param response {@link HttpServletRequest}
* @param token 要写入的 token
*/
public static void writeLoginToken(HttpServletResponse response, String token) {
Cookie cookie = new Cookie(LOGIN_TOKEN_NAME, token);
cookie.setDomain(COOKIE_DOMAIN);
cookie.setPath("/");
cookie.setHttpOnly(true);
// 保存时间,如果不设置,仅在当前窗口有效
// 单位秒,-1 表永久
cookie.setMaxAge(60 * 60);
log.info("write cookieName: {}, cookieValue: {}", cookie.getName(), cookie.getValue());
response.addCookie(cookie);
}
/**
* <h2>从 cookie 中获取 token</h2>
*
* @param request {@link HttpServletRequest}
* @return
*/
public static String readLoginToken(HttpServletRequest request) {
Cookie[] cookies = request.getCookies();
if (Objects.isNull(cookies)) {
return null;
}
for (Cookie cookie : cookies) {
if (Objects.nonNull(cookie.getName()) && cookie.getName().equals(LOGIN_TOKEN_NAME)) {
log.info("get target cookie-> cookieName: {}, cookieValue: {}", cookie.getName(), cookie.getValue());
return cookie.getValue();
}
}
return null;
}
/**
* <h2>如果存在 login cookie,删除该 cookie</h2>
*
* @param request {@link HttpServletRequest}
* @param response {@link HttpServletResponse}
*/
public static void delLoginToken(HttpServletRequest request, HttpServletResponse response) {
Cookie[] cookies = request.getCookies();
for (Cookie cookie : cookies) {
if (Objects.nonNull(cookie.getName()) && cookie.getName().equals(LOGIN_TOKEN_NAME)) {
cookie.setDomain(COOKIE_DOMAIN);
cookie.setPath("/");
// 设置为 0 表示删除 cookie
cookie.setMaxAge(0);
log.info("del cookie--> cookieName: {}, cookieValue: {}", cookie.getName(), cookie.getValue());
response.addCookie(cookie);
}
}
}
}
基于 cookie + redis的单点登录介绍
为啥要 cookie + redis ?
登录
- 生产一个 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 中的消息了