您好,登錄后才能下訂單哦!
本篇內容主要講解“SpringBoot怎么實現持久化登錄狀態獲取”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“SpringBoot怎么實現持久化登錄狀態獲取”吧!
寫入cookie
//登陸成功后 //...將用戶賬號信息存入數據庫中 //寫cookie,(因存入數據庫,無需寫入session了) response.addCookie(new Cookie("token",token));
@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"; } }
賬戶模塊中必要的功能登錄登出,相信這個大家都經常使用了。簡單介紹下在SpringBoot中的實現
先說下實現思路:
用戶名密碼存儲在數據庫中,前端發出請求,攔截器先檢測用戶有無登錄,若有登錄可直接請求接口。無需登錄就可請求的接口需要加@NoLogin自定義注解。若未登錄,前端跳轉到登錄頁面,調用登錄接口,系統在后臺驗證用戶名密碼,驗證通過將用戶信息存儲在redis中和線程上下文中。
除了必要的用戶名 密碼 其他賬戶信息字段大家可根據自己系統需求添加。
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端網點人員賬戶表';
接收客戶端傳參,調用接口與數據庫信息匹配,匹配成功返回用戶信息。并且存儲到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(); } }
創建一個請求攔截器,用于檢測用戶登錄態。通過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); } }
獲取到當前會話,清空回話信息,刪除redis中對應sessionid的用戶信息。代碼見上第二段代碼logout方法。
到此,相信大家對“SpringBoot怎么實現持久化登錄狀態獲取”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。