这是一种有关记住我功能的新实现方式

在传统的前后端不分离项目中,大家在登录界面应该经常能看到记住我这个功能,这个功能本质上是为了让用户能在一段较长时间内不在重复登录,在以前的实现方案中,大家多使用 cookie 实现,本文给大家介绍在引入了 spring-session-redis 的项目中,使用一种新的实现方式,直接设置 redis 中用户 session 的有效期来实现。

本文使用 newbeepro 项目作为示例,给大家演示记住我功能的具体实现。项目地址:github.com/wayn111/new...

本文大纲如下,

1. spring-session 的 yml 配置

在使用 spring-session 后,我们可以在 spring 的 yml 文件中设置 session 在 redis 中的 key 前缀,在 newbeepro 项目中,我们设置为 newbee_mall,然后我们设置过期时间 3600 秒,也就是一小时。

2. spring-session 的默认序列化方式

java 复制代码
@Configuration
public class CacheConfig implements CachingConfigurer {
    /**
     * 指定spring-session的默认序列化方式
     *
     * @return RedisSerializer
     */
    @Bean("springSessionDefaultRedisSerializer")
    public RedisSerializer<Object> redisSerializer() {
        return valueSerializer();
    }
    private RedisSerializer<Object> valueSerializer() {
        return new GenericFastJsonRedisSerializer();
    }
}

添加 RedisSerializer 类的 bean 实例,并且设置 bean 名称是 springSessionDefaultRedisSerializer。注意 bean 名称必须是 springSessionDefaultRedisSerializer。

这一步不是必须的,作用是可以设置 spring-session-redis 的默认序列化实现。当我们设置为 fastjson 的序列化方式时,就可以让我们方便的查看 redis 客户端。

3. 打开登录页面

当用户打开 newbeepro 项目前端页面时,用户 session 就已经在 redis 中保存了下来,这一点我们通过查看 redis 客户端发现,此时用户的 session 信息已经存在,并且有效期是 3600 秒与我们 yml 配置的过期时间是一致的。

4. 后端登录接口如何实现记住我

java 复制代码
@ResponseBody
@PostMapping("/login")
public R doLogin(MallUserVO mallUserVO,
                 @RequestParam("destPath") String destPath,
                 HttpSession session) {
    R success = R.success();
    MallUser user = mallUserService.getOne(Wrappers.<MallUser>lambdaQuery()
            .eq(MallUser::getLoginName, mallUserVO.getLoginName())
            .eq(MallUser::getPasswordMd5, Md5Utils.hash(mallUserVO.getPassword())));
    if (user == null) {
        return R.error("账户名称或者密码错误");
    }
    if (user.getLockedFlag() == 1) {
        return R.error("该账户已被禁用");
    }
    BeanUtils.copyProperties(user, mallUserVO);
    session.setAttribute(Constants.MALL_USER_SESSION_KEY, mallUserVO);
    String namespace = environment.getProperty("spring.session.redis.namespace");
    String sessionKey = namespace + ":sessions:" + session.getId()
    int timeout = Integer.parseInt(environment.getProperty("spring.session.timeout"));
    if (mallUserVO.isRememberme()) {
        redisCache.setCacheMapValue(sessionKey, "maxInactiveInterval", timeout * 24 * 7);
    } else {
        redisCache.setCacheMapValue(sessionKey, "maxInactiveInterval", timeout);
    }
    if (StringUtils.isNotEmpty(destPath) && StringUtils.contains(destPath, "=")) {
        success.add("destPath", destPath.split("=")[1].substring(1));
    }
    return success;
}

在登录接口中,我们可以通过 mallUserVO.isRememberme() 方法来判断用户是否点击了记住我按钮,在前面的第三步中,我们可以看到用户的 session 在 redis 中 的 key 名称是 newbee_mall:sessions:c3fd288e-c9c2-47e6-961b-a5e1e0a3205e。

这里给大家讲解一下这个 key 的拼接逻辑。

OK,根据这个拼接逻辑,我们拼接 session key 的实现代码就是,

java 复制代码
String namespace = environment.getProperty("spring.session.redis.namespace");
String sessionKey = namespace + ":sessions:" + session.getId()

然后大家在用户 session key 的 hash 内容里可以发现有一个 hashKey 名称是 maxInactiveInterval,它就是用户 session 的有效期属性,我们可以通过改变 maxInactiveInterval 的属性值来延长用户 session 的有效期,以此来实现记住我功能。

那我们就可以通过 redisCache 实例来直接设置用户 session 的有效期,代码如下,

java 复制代码
redisCache.setCacheMapValue(sessionKey, "maxInactiveInterval", timeout * 24 * 7)

5. 登录成功

当用户勾选了记住我按钮,登录成功后,我们来看下 redis 客户端,

OK,大功告成。

总结一下

本文给大家讲解了在使用 spring-session-redis 的项目中,如何通过延长用户 session 的有效期来达到记住我功能的一致效果。

大家在学习本文后,也可以把记住我功能应用到自己的项目中,本文实例代码都在 newbeepro 项目中可以找到。

如果觉得这篇文章写的不错的话,不妨点赞加关注,我会更新更多技术干货、项目教学、经验分享的文章。

相关推荐
噢,我明白了8 小时前
表单的完整 CRUD 练习【极简个人记账本】(含前端后端链接mySQL)
java·前端·数据库·mysql
通往曙光的路上8 小时前
mysql1
java
Tigshop开源商城12 小时前
『物流设置+SEO优化』Tigshop开源商城系统 JAVA v5.8.26 版本更新!
java·开源商城系统·tigshop
Tigshop开源商城14 小时前
『订单税率+收货地址校验国家字段』功能上新|跨境运营更高效,Tigshop开源商城系统 JAVA v5.8.23 版本更新
java·开源商城系统·tigshop
养肥胖虎14 小时前
Docker学习笔记:后端、数据库和反向代理怎么一起跑起来
后端·nginx·docker·postgresql·go·部署
REDcker14 小时前
C++变量存储与ELF段布局详解 从const全局到rodata与nm_readelf验证实践
java·c++·面试
晓杰'15 小时前
从0到1实现 Balatro 游戏后端(2):NestJS框架搭建与项目结构设计
后端·websocket·typescript·node.js·游戏开发·项目实战·nestjs
无所事事O_o15 小时前
二次验证码TOTP 使用说明
后端·二次验证码·谷歌验证器
ltl16 小时前
Multi-Head Attention:为什么要分多个头
后端
kobesdu16 小时前
【ROS2实战笔记-19】ROS2 生命周期节点的启动顺序、状态转换陷阱与热备方案
java·前端·笔记·机器人·ros·ros2