常见分布式session会话方案

实现分布式session的方案非常多,选型时需要一种可靠、简单的实现方式,结合我们项目中的使用经验来看,使用基于Redis实现的分布式session方案还是比较靠谱的,同时,项目中还把session信息存储在cookie里面,多一层保障。

基本原理

使用Redis作为session存储容器,登录时将session信息存储至cookie客户端,同时服务端将session信息存至redis缓存,双重保障,接下来的接口调用直接可以获取到cookie中的token信息作为参数传递进来即可,如果发现token为空,则再从redis中获取,如果两者都为空,则说明session已过期。

代码实现

    private static String redisKey = "user:session";

    /**
     * 登录成功后生成并保存token
     *
     * @param response
     * @param user
     * @return
     */
    public boolean login(HttpServletResponse response, User user) {
        // 验证用户身份
        User user = userService.check(……);
        //  salt值建议做成可配置化
        String salt = "";
        String token = DigestUtils.md5Hex(user.getName() + salt);   //这里token作为用户信息唯一标识
        addCookie(response, token);
        return true;
    }

    /**
     * 添加至redis和cookie
     *
     * @param response
     * @param token
     */
    private void addCookie(HttpServletResponse response, String token) {
        redisTemplate.opsForValue().set(redisKey, token, 366, TimeUnit.DAYS);//放入缓存
        Cookie cookie = new Cookie("token", token);
        cookie.setMaxAge(3600 * 24 * 366);   //和Redis缓存失效时间一致
        cookie.setPath("/");
        response.addCookie(cookie);
    }

    /**
     * 获取已登录的用户信息
     * @param response
     * @return
     */
    public String getByToken(HttpServletResponse response) {
        String userinfo = redisTemplate.opsForValue().get(redisKey);
        //延长session有效期,过期时间=最后一次使用+失效时间,cookie可以不延长
        if (StringUtils.isNotEmpty(userinfo)) {
            addCookie(response, userinfo);
        }
        return userinfo;
    }

从本人现在所做的项目来看,也是采用了这用做法,因为我们模块分的很细,登录一类的功能是其它部门做的,也是将token放在cookie客户端,然后接口交互都带上这个参数来检验接口的合法性。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐