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逻辑

@Controller
public class IndexController {
    @Autowired
    private 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 = WebConstants.WEB_PREFIX + "/account")
@Api(tags = "Account", description = "账户模块")
@NoAuth
public class AccountController {
    @Autowired
    private AccountService accountService;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @PostMapping(value = "/login")
    @ApiOperation("登录")
    public ResponseVo<AccountVo>login(@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 = "/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的缓存),便于后续使用。这一步也可以放在登录成功后(这样也更严谨)。

@Component
public class LoginInterceptor implements HandlerInterceptor {
    private Logger logger= LoggerFactory.getLogger(LoginInterceptor.class);
    @Autowired
    private StringRedisTemplate redisTemplate;

    @Override
    public 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中是否含有sessionId
            String 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);
                throw  new BizException("401","common.system.user.not.login");
            }
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    }
}

注册拦截器:(注册后的拦截器才会生效哦)

@Configuration
public class WebConfiguration extends WebMvcConfigurationSupport {
    @Autowired
    private LoginInterceptor loginInterceptor;
    /**
     * 拦截器配置
     *
     * @param registry 注册类
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginInterceptor).addPathPatterns(WebConstants.WEB_PREFIX + "/**");
        super.addInterceptors(registry);
    }
}

4.登出

获取到当前会话,清空回话信息,删除redis中对应sessionid的用户信息。代码见上第二段代码logout方法。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • SpringBoot持久化层操作支持技巧

    SpringBoot的持久化层可以是Spring内置的轻量级JdbcTemplate.也可以是Hibernate或Mybatis等等,只需要在在工程pom.xml文件中添加对应的依赖就可以了. 新建工程我们能发现,SpringBoot对数据库操作的支持有以下几种: 可见SpringBoot对各种的支持还是挺多的. 入正题.看看对SQL的支持.主要选了比较传统/流行/有前景的4个进行操作: 均是采用mysql. 所以应该添加对mysql操作的依赖: <!--MySQL--> <depend

  • SpringBoot中使用Cookie实现记住登录的示例代码

    最近在做项目,甲方提出每次登录都要输入密码,会很麻烦,要求实现一个记住登录状态的功能,于是便使用 Cookie 实现该功能 一.Cookie 简介 Cookie,一种储存在用户本地终端上的数据,有时也用其复数形式 Cookies.类型为"小型文本文件",是某些网站为了辨别用户身份,进行 Session 跟踪而储存在用户本地终端上的数据(通常经过加密),由用户客户端计算机暂时或永久保存的信息. 其实 Cookie 就是一个键和一个值构成的,随着服务器端的响应发送给客户端浏览器.然后客户端

  • SpringBoot集成JPA持久层框架,简化数据库操作

    目录 与SpringBoot2.0整合 1.核心依赖 2.配置文件 3.实体类对象 4.JPA框架的用法 5.封装一个服务层逻辑 测试代码块 源代码地址 与SpringBoot2.0整合 1.核心依赖 <!-- JPA框架 --> <dependency>     <groupId>org.springframework.boot</groupId>     <artifactId>spring-boot-starter-data-jpa<

  • springboot+quartz以持久化的方式实现定时任务的代码

    这篇文章给大家介绍springboot+quartz以持久化的方式实现定时任务,详情如下所示: 篇幅较长,耐心的人总能得到最后的答案小生第一次用quartz做定时任务,不足之处多多谅解. 首先 在springboot项目里做定时任务是比较简单的,最简单的实现方式是使用**@Scheduled注解,然后在application启动类上使用@EnableScheduling**开启定时任务. 示例 @SpringBootApplication @EnableScheduling public cla

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

    目录 SpringBoot 持久化登录状态获取 1.编写登录的controller文件 2.编写首页Controller逻辑 3.运行测试,成功 SpringBoot 实现登录登出,登录态管理 1.设计表结构 2.controller层 3.创建请求拦截器 4.登出 SpringBoot 持久化登录状态获取 1.编写登录的controller文件 写入cookie //登陆成功后 //...将用户账号信息存入数据库中 //写cookie,(因存入数据库,无需写入session了) respons

  • 微信小程序获取用户信息并保存登录状态详解

    前言 微信小程序的运行环境不是在浏览器下运行的.所以不能以cookie来维护登录态.下面我就来说说我根据官方给出的方法来写出的维护登录态的方法吧. 一.登录态维护 官方的文档地址:https://mp.weixin.qq.com/debug/wxadoc/dev/api/api-login.html#wxloginobject 通过 wx.login() 获取到用户登录态之后,需要维护登录态.开发者要注意不应该直接把 session_key.openid 等字段作为用户的标识或者 session

  • Springboot+Shiro记录用户登录信息并获取当前登录用户信息的实现代码

    由于最近做项目需要,在用户登陆后有一个功能是需要用户的信息,进行写入数据库的操作.但是目前还用不到Shiro的高级权限,只为了简单获取用户信息,自己整合了一个只记录用户,获取用户信息的功能. 导入Shiro依赖 <!-- Shiro --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version

  • Vue注册模块与登录状态的持久化实现方法详解

    目录 整体框架 1. 前端页面授权 2. 实现注册页面 3. 实现登录状态的持久化 优化前端 整体框架 1. 前端页面授权 当我们登录网站的时候,如果没有登录,强制让用户重定向到 登录界面 在 router 目录下的 index.js 文件下实现. router -> index.js import store from '../store/index' // 把一些额外信息放到一个额外的域里面,meta信息里面存一下是否要授权,如果需要授权而且没有登录,重定向到登录页面,重定向到登录界面. c

  • springboot 微信授权网页登录操作流程

    操作流程 假设你已经有自己的域名,因为微信公众号和微信回调都需要域名 先看看官方给的文档 根据官方文档,主要流程如下: (1)引导用户进入授权页面同意授权,获取code (2)通过code换取网页授权access_token(与基础支持中的access_token不同) (3)刷新access_token(如果有需要) (3)通过网页授权access_token和openid获取用户基本信息 提示:以下是本篇文章正文内容,下面案例可供参考 编写微信授权方法和获取用户信息方法 二.使用步骤 获取微

  • SpringBoot JWT实现token登录刷新功能

    目录 1. 什么是JWT 2. JWT组成部分 3. JWT加密方式 4.实战 5.总结 1. 什么是JWT Json web token (JWT) 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准.简答理解就是一个身份凭证,用于服务识别. JWT本身是无状态的,这点有别于传统的session,不在服务端存储凭证.这种特性使其在分布式场景,更便于扩展使用. 2. JWT组成部分 JWT有三部分组成,头部(header),载荷(payload),是签名(signature). 头

  • springboot整合shiro实现登录验证授权的过程解析

    springboot整合shiro实现登录验证授权,内容如下所示: 1.添加依赖: <!-- shiro --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.7.1</version> </dependency> 2.yml配置: #配置服务端口 s

  • vue+springboot+shiro+jwt实现登录功能

    目录 1.导入依赖 2.JWTToken 替换 Shiro 原生 Token 3.JWT token 工具类,提供JWT生成.校验.获取token存储的信息 4.JWTFilter请求拦截 5.登录授权realm 6.shiro配置 7.登录web端 8.异常处理 9.缓存调用登录接口传过来的token 10.请求头设置,带上token 11.生产环境nginx配置 公司开发的系统原先的用户信息是基于shiro session 进行管理,但是session不适用于app端,并且服务器重启后需要重

  • AngularJS实现用户登录状态判断的方法(Model添加拦截过滤器,路由增加限制)

    本文实例讲述了AngularJS实现用户登录状态判断的方法.分享给大家供大家参考,具体如下: 使用AngularJS的单页面应用时,由于是本地路由在控制页面跳转,但是有的时候我们需要判断用户是否登录来判断用户是否能进入界面. angularjs是mvc架构所以实现起来很容易也很灵活,我们只MainController里增加一个路由事件侦听并判断,这样就可以避免未登录用户直接输入路由地址来跳转到登录界面地址了 代码中的 $rootScope.user是登录后把用户信息放到了全局rootScope上

随机推荐