Session子Web项目出现以来,一直都存在。
最近在开发集群项目,想到Session的处理,介于之前做过一个Session集群处理的
spring-session-data-redis
这个是集成spring + redis的一个session管理。
使用很好,但是,对于管理session有些不方便。
所以,我就自己写了一个Session管理的。
springboot Interceptor + redis 来拦截请求。
1.判断是否登录
public static boolean isLogin(HttpServletRequest request) { // 获取cookie值 String cookieValue = CookieUtil.getCookieValue(request, ZIPPER_TOKEN_WEB_COOKIE_NAME); // cookie值不存在,表示未登录 if(StringUtil.isNullOrEmpty(cookieValue)) { return false; } // 验证 redis expires 中是否存在 token 值 RedisUtil.Strings s = RedisUtil.getInstance().new Strings(); if(!s.exists(DB_INDEX, getTokenExpiresKey(cookieValue))) { return false; } // 更新token时间 long r1 = s.expire(DB_INDEX, getTokenExpiresKey(cookieValue), TIME_OUT); if(r1 == 0) { // 命中失败,重新添加缓存值 s.setEx(DB_INDEX, getTokenExpiresKey(cookieValue), TIME_OUT, ""); } s.expire(DB_INDEX, getTokenKey(cookieValue), TIME_OUT_DATA); return true; }
2.用户登录,创建Token
public static String createToken(UserModel record, List<MenuModel> menuList) { // 生成 token UUID uuid = UUID.randomUUID(); String token = uuid.toString(); RedisUtil.Strings s = RedisUtil.getInstance().new Strings(); RedisUtil.Hash h = RedisUtil.getInstance().new Hash(); // 设置 expire token s.setEx(DB_INDEX, getTokenExpiresKey(token), TIME_OUT, ""); // 设置 data token String tokenKey = getTokenKey(token); LoginUser loginUser = new LoginUser(record); h.hset(DB_INDEX, tokenKey, LOGIN_USER, loginUser.toString()); // 根据已知代码,menuList有可能是null if(null != menuList) { h.hset(DB_INDEX, tokenKey, MENU_LIST, JSONObject.toJSONString(menuList)); } s.expire(DB_INDEX, tokenKey, TIME_OUT_DATA); // 返回token return token; }
用户登录成功之后,把Token存在Cookie中。
// 创建 token String token = W.createToken(userModel, menuList); // 设置 cookie CookieUtil.setCookie(request, response, W.ZIPPER_TOKEN_WEB_COOKIE_NAME, token, W.ZIPPER_TOKEN_WEB_COOKIE_TIME_OUT);
3.用户注销,删除Token
/** 根据token删除 */ public static boolean deleteToken(HttpServletRequest request) { // 获取cookie值 String cookieValue = CookieUtil.getCookieValue(request, ZIPPER_TOKEN_WEB_COOKIE_NAME); if(StringUtil.isNullOrEmpty(cookieValue)) { // token 不存在 return true; } // 删除 expire token RedisUtil.Strings s = RedisUtil.getInstance().new Strings(); Long r = s.del(DB_INDEX, getTokenExpiresKey(cookieValue)); // 删除 data token RedisUtil.Hash h = RedisUtil.getInstance().new Hash(); h.hdel(DB_INDEX, getTokenKey(cookieValue)); return (r == 1); }
用户注销,删除Token信息
W.deleteToken(request);
4.获取用户信息,菜单信息等。
/** 获取登录用户信息 */ public static LoginUser getLoginUser(HttpServletRequest request) { // 获取cookie值 String cookieValue = CookieUtil.getCookieValue(request, ZIPPER_TOKEN_WEB_COOKIE_NAME); if(StringUtil.isNullOrEmpty(cookieValue)) { // token 不存在 return null; } RedisUtil.Hash h = RedisUtil.getInstance().new Hash(); String value = h.hget(DB_INDEX, getTokenExpiresKey(cookieValue), LOGIN_USER); if(StringUtil.isNullOrEmpty(value)) { return null; } return JSONObject.parseObject(value, LoginUser.class); } /** 获取登录用户菜单信息 */ public static List<MenuModel> getMenuList(HttpServletRequest request) { // 获取cookie值 String cookieValue = CookieUtil.getCookieValue(request, ZIPPER_TOKEN_WEB_COOKIE_NAME); if(StringUtil.isNullOrEmpty(cookieValue)) { // token 不存在 return null; } RedisUtil.Hash h = RedisUtil.getInstance().new Hash(); String value = h.hget(DB_INDEX, getTokenKey(cookieValue), MENU_LIST); if(StringUtil.isNullOrEmpty(value)) { return null; } return JSONObject.parseArray(value, MenuModel.class); }
Redis存储结构
这样,一个自定义的无session管理系统,就开发完成了。