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

网友投稿 1228 2022-11-24

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

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")){

FySBAxYl 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 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 = "/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();

http:// 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方法

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:【Go】资源竟态检测工具:race detetor
下一篇:「无服务器架构」动手操作Knative -第二部分
相关文章

 发表评论

暂时没有评论,来抢沙发吧~