完整的redis保存用户信息,cookie保存sessionId实现登录流程



1. 完整的redis保存用户信息,cookie保存sessionId实现登录流程

登录流程

  1. cookid中存入sessionId并持久化到本地,把它的过期时间设置长一点
//1. 把登录信息存入cookie 中
CookieUtil.writeLoginToken(httpServletResponse,session.getId());
-----------------》writeLoginToken()方法
    /**
     * 存入cookie到本地
     */
    public static void writeLoginToken(HttpServletResponse response,String token){
        Cookie ck = new Cookie(COOKIE_NAME,token);
        //跨域共享,设置的值是B机器的域名,所以当B机器访问这个Cookie的时候是能访问到的
        ck.setDomain(COOKIE_DOMAIN);
        //代表设置在根目录
        ck.setPath("/");
        ck.setHttpOnly(true);
        //单位是秒。如果这个maxAge不设置的话,cookie就不会写入硬盘,而是写在内存。只在当前页面有效。
        //如果是-1,代表永久
        ck.setMaxAge(60 * 60 * 24 * 365);
        log.info("write cookieName:{},cookieValue:{}",ck.getName(),ck.getValue());
        response.addCookie(ck);
    }


  1. redis中存入用户信息(value),存入之前把用户信息转换成json格式,把sessionId作为key,并设置过期时间
//2. 把登录信息存入redis 中(response.getData()获得了查询出来的user对象)
RedisShardedPoolUtil.setEx(session.getId(), JsonUtil.obj2String(response.getData()),Const.RedisCacheExtime.REDIS_SESSION_EXTIME);

-----------------》setEx()/**
     * 存入一个值并设置过期时间
     */
    //exTime的单位是秒
    public static String setEx(String key,String value,int exTime){
        ShardedJedis jedis = null;
        String result = null;
        try {
            jedis = RedisShardedPool.getJedis();
            result = jedis.setex(key,exTime,value);
        } catch (Exception e) {
            log.error("setex key:{} value:{} error",key,value,e);
            RedisShardedPool.returnBrokenResource(jedis);
            return result;
        }
        RedisShardedPool.returnResource(jedis);
        return result;
    }








访问流程

  1. 添加一个过滤器,每次访问.do结尾的方法,都会经过过滤器并重置redis中存储用户信息的时间
--------------》过滤器主要方法
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest)servletRequest;

        //1. 从cookie中获取value值(也就是session的值)
        String loginToken = CookieUtil.readLoginToken(httpServletRequest);
-----------》readLoginToken方法
/**
 * 获取存储的cookie
 */
public static String readLoginToken(HttpServletRequest request){
    Cookie[] cks = request.getCookies();
    if(cks != null){
        for(Cookie ck : cks){
            log.info("read cookieName:{},cookieValue:{}",ck.getName(),ck.getValue());
            if(StringUtils.equals(ck.getName(),COOKIE_NAME)){
                log.info("return cookieName:{},cookieValue:{}",ck.getName(),ck.getValue());
                return ck.getValue();
            }
        }
    }
    return null;
}



        //2. 如果value不为空
        if(StringUtils.isNotEmpty(loginToken)){

            //2.1 通过session(也就是cookie的value和redis中的key)值获取用户信息
            String userJsonStr = RedisShardedPoolUtil.get(loginToken);
--------------get方法
/**
 * 通过key获取一个值
 */
public static String get(String key){
    ShardedJedis jedis = null;
    String result = null;
    try {
        jedis = RedisShardedPool.getJedis();
        result = jedis.get(key);
    } catch (Exception e) {
        log.error("get key:{} error",key,e);
        RedisShardedPool.returnBrokenResource(jedis);
        return result;
    }
    RedisShardedPool.returnResource(jedis);
    return result;
}


            User user = JsonUtil.string2Obj(userJsonStr,User.class);
--------------------》string2Obj方法
/**
 *将json格式转换成匹配的对象或者集合;(1)
 *
 * @param str 要转换的json字符串
 * @param clazz 要转换成的类型
 */
public static <T> T string2Obj(String str,Class<T> clazz){
    if(StringUtils.isEmpty(str) || clazz == null){
        return null;
    }

    try {
        return clazz.equals(String.class)? (T)str : objectMapper.readValue(str,clazz);
    } catch (Exception e) {
        log.warn("Parse String to Object error",e);
        return null;
    }
}


            //2.2如果成功获取值,重新设置一个redis中的过期时间(因为每次拿到的用户信息就是从reids中拿的)
            if(user != null){
                //如果user不为空,则重置session的时间,即调用expire命令
                RedisShardedPoolUtil.expire(loginToken, Const.RedisCacheExtime.REDIS_SESSION_EXTIME);
--------------------------------》expire方法
/**
 * 设置key的有效期,单位是秒
 */
public static Long expire(String key,int exTime){
    ShardedJedis jedis = null;
    Long result = null;
    try {
        jedis = RedisShardedPool.getJedis();
        result = jedis.expire(key,exTime);
    } catch (Exception e) {
        log.error("expire key:{} error",key,e);
        RedisShardedPool.returnBrokenResource(jedis);
        return result;
    }
    RedisShardedPool.returnResource(jedis);
    return result;
}
      
            }
        }

        //3. 放行
        filterChain.doFilter(servletRequest,servletResponse);
    }

  1. (访问了方法)获取redis中存入的登录信息
		//1. 获取redis中存入的登录信息
        String userJsonStr = RedisShardedPoolUtil.get(loginToken);
 -------------------get方法上面有
  1. 并转化成对象格式

        //2. 转换成user对象格式
        User user = JsonUtil.string2Obj(userJsonStr,User.class);
------------》string2Obj方法上面也有,注意这里只是一个类型转换








退出流程

  1. 删除cookie

        //1. 删除cookie
        CookieUtil.delLoginToken(httpServletRequest,httpServletResponse);
 --------------》delLoginToken方法
     /**
     * 删除本地cookie
     */
    public static void delLoginToken(HttpServletRequest request,HttpServletResponse response){
        Cookie[] cks = request.getCookies();
        if(cks != null){
            for(Cookie ck : cks){
                if(StringUtils.equals(ck.getName(),COOKIE_NAME)){
                    ck.setDomain(COOKIE_DOMAIN);
                    ck.setPath("/");
                    ck.setMaxAge(0);//设置成0,代表删除此cookie。
                    log.info("del cookieName:{},cookieValue:{}",ck.getName(),ck.getValue());
                    response.addCookie(ck);
                    return;
                }
            }
        }
    }
  1. 删除redis

        //2. 删除redis
        RedisShardedPoolUtil.del(loginToken);
----------------》del方法
    /**
     * 删除一个值
     */
    public static Long del(String key){
        ShardedJedis jedis = null;
        Long result = null;
        try {
            jedis = RedisShardedPool.getJedis();
            result = jedis.del(key);
        } catch (Exception e) {
            log.error("del key:{} error",key,e);
            RedisShardedPool.returnBrokenResource(jedis);
            return result;
        }
        RedisShardedPool.returnResource(jedis);
        return result;
    }




注意

  1. 例如登录流程之类的,他们是同一个方法中的两个步骤,只截取了主要部分,下面特意把它们使用的方法都写出来了,都是自己写好的工具类
  2. 注意设置的setDomain属性,因为nginx有两台tomcat,所以要实现单点登录,所以我们就要保证域名是一级域名,a和b两台服务器都能访问到的那种,这样两个tomcat才可以访问同一个cookie

猜你喜欢

转载自blog.csdn.net/qq_36354011/article/details/88677985