SpringBoot如何实现持久化登录状态获取

目录

  • SpringBoot 持久化登录状态获取
    • 1.编写登录的controller文件
    • 2.编写首页Controller逻辑
    • 3.运行测试,成功
  • SpringBoot 实现登录登出,登录态管理
    • 1.设计表结构
    • 2.controller层
    • 3.创建请求拦截器
    • 4.登出

SpringBoot 持久化登录状态获取
1.编写登录的controller文件
写入cookie
//登陆成功后//...将用户账号信息存入数据库中//写cookie,(因存入数据库,无需写入session了)response.addCookie(new Cookie("token",token));


2.编写首页Controller逻辑
@Controllerpublic class IndexController {@Autowiredprivate UserMapper userMapper; @GetMapping("/")public String index(HttpServletRequest request){Cookie[] cookies = request.getCookies(); if (cookies != null){for (Cookie cookie : cookies) {if (cookie.getName().equals("token")){String token = cookie.getValue(); System.out.println("准备进数据库"); User user = userMapper.findByToken(token); //去数据库寻找该token值的用户信息System.out.println(user.toString()); if(user != null){ //若找到了这个用户信息//写进session,让页面去展示request.getSession().setAttribute("user",user); }break; }}}return "index"; }}


3.运行测试,成功

SpringBoot 实现登录登出,登录态管理 账户模块中必要的功能登录登出,相信这个大家都经常使用了。简单介绍下在SpringBoot中的实现
先说下实现思路:
用户名密码存储在数据库中,前端发出请求,拦截器先检测用户有无登录,若有登录可直接请求接口。无需登录就可请求的接口需要加@NoLogin自定义注解。若未登录,前端跳转到登录页面,调用登录接口,系统在后台验证用户名密码,验证通过将用户信息存储在redis中和线程上下文中。

1.设计表结构
除了必要的用户名 密码 其他账户信息字段大家可根据自己系统需求添加。
CREATE TABLE `t_account` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',`name` varchar(64) NOT NULL DEFAULT '' COMMENT '姓名',`mobile` varchar(32) NOT NULL COMMENT '手机号',`identity` varchar(32) NOT NULL COMMENT '身份证号码',`user_name` varchar(32) NOT NULL COMMENT '账户',`password` varchar(64) NOT NULL DEFAULT '' COMMENT '登录密码',`accept_region` bigint(20) NOT NULL COMMENT '受理中心(网点)编号',`status` int(11) NOT NULL DEFAULT '1' COMMENT '状态:0 禁用,1 正常,9 删除',`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',`create_by` bigint(20) DEFAULT NULL COMMENT '创建人Id',`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',`update_by` bigint(20) DEFAULT NULL COMMENT '修改人Id',PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='C端网点人员账户表';


2.controller层
接收客户端传参,调用接口与数据库信息匹配,匹配成功返回用户信息。并且存储到redis中,且以当前回话sessionid为key,用户信息为value。
@RestController@RequestMapping(value = https://www.it610.com/article/WebConstants.WEB_PREFIX +"/account")@Api(tags = "Account", description = "账户模块")@NoAuthpublic class AccountController { @Autowiredprivate AccountService accountService; @Autowiredprivate StringRedisTemplate redisTemplate; @PostMapping(value = "https://www.it610.com/login")@ApiOperation("登录")public ResponseVologin(@RequestBody LoginForm form, HttpServletRequest request,HttpServletResponse response){ HttpSession session=request.getSession(); AccountDto accountDto=accountService.login(form.getUserName(),form.getPassword()); if(null==accountDto){throw new BizException("用户名或密码错误!"); }redisTemplate.opsForValue().set(session.getId(), JSON.toJSONString(accountDto)); AccountVo accountVo= BeanCopy.of(accountDto,new AccountVo()).copy(BeanUtils::copyProperties).get(); accountVo.setAceptRegion(AcceptRegionEnum.getDescByValue(accountDto.getAceptRegion())); return ResponseVo.successResponse(accountVo); } @Login@PostMapping(value = "https://www.it610.com/logout")@ApiOperation("登出")public ResponseVo logout(HttpServletRequest request,HttpServletResponse response){HttpSession session=request.getSession(); session.invalidate(); redisTemplate.delete(session.getId()); return ResponseVo.successResponse(); } }


3.创建请求拦截器
创建一个请求拦截器,用于检测用户登录态。通过session_id检测redis中有没有用户信息。如果存在则将用户信息存储当前线程上下文中(用户线程上下文实质就是基于HashMap的缓存),便于后续使用。这一步也可以放在登录成功后(这样也更严谨)。
@Componentpublic class LoginInterceptor implements HandlerInterceptor { private Logger logger= LoggerFactory.getLogger(LoginInterceptor.class); @Autowiredprivate StringRedisTemplate redisTemplate; @Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { HandlerMethod handlerMethod = (HandlerMethod) handler; Class clazz = handlerMethod.getBeanType(); Method m = handlerMethod.getMethod(); //需登录才可以访问的(预约核验模块)if (clazz.isAnnotationPresent(NoLogin.class) || m.isAnnotationPresent(NoLogin.class)) {return true; }HttpSession session=request.getSession(); //检测redis中是否含有sessionIdString val=redisTemplate.opsForValue().get(session.getId()); if(null!=val){logger.info(val); AccountDto accountDto= JSON.parseObject(val,AccountDto.class); AcceptRegionUserVistor vistor=new AcceptRegionUserVistor(); BeanUtils.copyProperties(accountDto,vistor); AcceptRegionUserThreadContext.putSessionVisitor(vistor); return true; }else{response.setStatus(401); thrownew BizException("401","common.system.user.not.login"); }} @Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } @Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { }}

注册拦截器:(注册后的拦截器才会生效哦)
@Configurationpublic class WebConfiguration extends WebMvcConfigurationSupport {@Autowiredprivate LoginInterceptor loginInterceptor; /*** 拦截器配置** @param registry 注册类*/@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(loginInterceptor).addPathPatterns(WebConstants.WEB_PREFIX + "/**"); super.addInterceptors(registry); }}


4.登出
获取到当前会话,清空回话信息,删除redis中对应sessionid的用户信息。代码见上第二段代码logout方法。
【SpringBoot如何实现持久化登录状态获取】以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

    推荐阅读