<dependency> <groupId>org.springframework.boot </groupId> <artifactId>spring-boot-starter-data-redis </artifactId> </dependency> <dependency> <groupId>org.springframework.session </groupId> <artifactId>spring-session-data-redis </artifactId> </dependency>
#redis spring.redis.host = 127.0 . 0.1 spring.redis.port = 6379 spring.redis.password = 123456 spring.redis.pool.max-idle = 8 spring.redis.pool.min-idle = 0 spring.redis.pool.max-active = 8 spring.redis.pool.max-wait =- 1 #超时一定要大于0 spring.redis.timeout = 3000 spring.session.store-type =redis
在配置redis时需要确保redis安装正确,并且配置notify-keyspace-events Egx,spring.redis.timeout设置为大于0,我当时这里配置为0时springboot时启不起来。
//拦截登录失效的请求 public class RedisSessionInterceptor implements HandlerInterceptor { @Autowired private StringRedisTemplate redisTemplate; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //无论访问的地址是不是正确的,都进行登录验证,登录成功后的访问再进行分发,404的访问自然会进入到错误控制器中 HttpSession session = request.getSession(); if (session.getAttribute( "loginUserId" ) != null ) { try { //验证当前请求的session是否是已登录的session String loginSessionId = redisTemplate.opsForValue().get( "loginUser:" + ( long ) session.getAttribute( "loginUserId" )); if (loginSessionId != null && loginSessionId.equals(session.getId())) { return true ; } } catch (Exception e) { e.printStackTrace(); } } response401(response); return false ; } private void response401(HttpServletResponse response) { response.setCharacterEncoding( "UTF-8" ); response.setContentType( "application/json; charset=utf-8" ); try { response.getWriter().print(JSON.toJSONString( new ReturnData(StatusCode.NEED_LOGIN, "" , "用户未登录!" ))); } catch (IOException e) { e.printStackTrace(); } } @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 WebSecurityConfig extends WebMvcConfigurerAdapter { @Bean public RedisSessionInterceptor getSessionInterceptor() { return new RedisSessionInterceptor(); } @Override public void addInterceptors(InterceptorRegistry registry) { //所有已api开头的访问都要进入RedisSessionInterceptor拦截器进行登录验证,并排除login接口(全路径)。必须写成链式,分别设置的话会创建多个拦截器。 //必须写成getSessionInterceptor(),否则SessionInterceptor中的@Autowired会无效 registry.addInterceptor(getSessionInterceptor()).addPathPatterns( "/api/**" ).excludePathPatterns( "/api/user/login" ); super .addInterceptors(registry); } }
@RestController @RequestMapping(value = "/api/user") public class LoginController { @Autowired private UserService userService; @Autowired private StringRedisTemplate redisTemplate; @RequestMapping("/login") public ReturnData login(HttpServletRequest request, String account, String password) { User user = userService.findUserByAccountAndPassword(account, password); if (user != null) { HttpSession session = request.getSession(); session.setAttribute( "loginUserId", user.getUserId()); redisTemplate.opsForValue(). set( "loginUser:" + user.getUserId(), session.getId()); return new ReturnData(StatusCode.REQUEST_SUCCESS, user, "登录成功!"); } else { throw new MyException(StatusCode.ACCOUNT_OR_PASSWORD_ERROR, "账户名或密码错误!"); } } @RequestMapping(value = "/getUserInfo") public ReturnData get(long userId) { User user = userService.findUserByUserId(userId); if (user != null) { return new ReturnData(StatusCode.REQUEST_SUCCESS, user, "查询成功!"); } else { throw new MyException(StatusCode.USER_NOT_EXIST, "用户不存在!"); } }}