SpringBoot+SpringSession+Redis 세 션 공유 및 유일한 로그 인 예제 구현

최근 에 spring boot 를 공부 하고 있 습 니 다.session 이라는 점 은 저 를 오랫동안 괴 롭 혔 습 니 다.오늘 은 이 날 밟 은 구 덩이 를 공유 하 세 요.더 많은 사람들 에 게 도움 이 되 었 으 면 좋 겠 습 니 다.
1.pom.xml 설정 

<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>
2.application.properties 의 redis 설정

#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 를 켤 수 없 었 습 니 다.
3.로그 인 상태 차단기 RedisSessionInterceptor 작성

//         
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
    {
 
    }
}
4.차단기 설정

@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);
    }
}
5.로그 인 컨트롤 러

@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, "     !");
        }
    }
}
효과
저 는 브 라 우 저 에 로그 인 한 후에 사용자 정 보 를 얻 고 postman 에 같은 계 정 을 로그 인 합 니 다.브 라 우 저 는 사용자 정 보 를 얻 으 면 401 오류 가 발생 합 니 다.브 라 우 저 는 다시 로그 인 해 야 사용자 정 보 를 얻 을 수 있 습 니 다.마찬가지 로 postman 에 로그 인 한 계 정 은 효과 가 없습니다.
브 라 우 저:


postman:

7.핵심 원리 에 대한 상세 한 해석
분산 식 session 은 두 가지 난점 을 해결 해 야 합 니 다.1.redis 를 정확하게 설정 하여 springboot 가 session 을 redis 서버 에 위탁 하도록 해 야 합 니 다.2,유일한 로그 인.
1、redis:
redis 는 다음 과 같은 효과 가 나타 날 때 까지 정확하게 시작 해 야 redis 의 정상 적 인 설정 과 시작 을 증명 할 수 있 습 니 다.

동시에 설정 이 정확 하 다 는 것 을 보증 해 야 한다.

@EnableCaching
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 30)//session    ( )
@Configuration
public class RedisSessionConfig
{
    @Bean
    public static ConfigureRedisAction configureRedisAction()
    {
        // springSession    config  
        return ConfigureRedisAction.NO_OP;
    }
}
spring boot 가 시 작 된 후 redis 에서 캐 시 를 찾 을 수 있 는 session 만 전체 redis+springboot 설정 이 성공 했다 는 것 을 설명 할 수 있 습 니 다!

2,유일한 로그 인:
1.사용자 가 로그 인 할 때 redis 에 해당 userId 에 대응 하 는 sessionId 를 기록 하고 userId 를 session 에 저장 합 니 다.

HttpSession session = request.getSession();
session.setAttribute("loginUserId", user.getUserId());
redisTemplate.opsForValue().set("loginUser:" + user.getUserId(), session.getId());
2.인터페이스 에 접근 할 때 RedisSession Interceptor 차단기 에 있 는 preHandle()에서 캡 처 한 다음 에 이 요청 발기인 의 session 에 저 장 된 userId 에 따라 현재 로그 인 된 session Id 를 redis 로 찾 습 니 다.찾 은 session Id 가 방문 자의 session Id 와 같 으 면 요청 이 합 법 적 이 고 통과 할 수 있 습 니 다.그렇지 않 으 면 401 이상 을 던 져 서 클 라 이언 트 401 상태 로 되 돌려 줍 니 다.
유일한 로그 인 은 제 검증 을 거 친 후에 수 요 를 만족 시 켰 습 니 다.잠시 문제 가 발생 하지 않 았 습 니 다.문제 가 있 는 지 없 는 지 보 여 주 셨 으 면 좋 겠 습 니 다.있 으 면 좋 은 건 의 를 해 주세요!
SpringBoot+SpringSession+Redis 가 session 공유 및 유일한 로그 인 예 시 를 실현 하 는 것 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 SpringBoot 의 유일한 로그 인 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 많은 응원 부탁드립니다!

좋은 웹페이지 즐겨찾기