Notice
Recent Posts
Recent Comments
Link
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
Tags
more
Archives
Today
Total
관리 메뉴

개발자 되버리기

SpringBoot에서 Docker Redis를 이용해 jwt 로그아웃 처리하기 본문

개발/Spring_Boot

SpringBoot에서 Docker Redis를 이용해 jwt 로그아웃 처리하기

구본익 2020. 12. 5. 18:20

JWT의 장점은 세션을 사용하지 않기에 서버의 자원을 효과적으로 사용할 수 있다는 것에 장점이 있습니다.

장점도 분명 존재하지만 단점도 있고

그 단점중 하나는 로그아웃에 관련된 내용입니다.

 

 

우선 도커를 이용해 간단하게 Redis를 설치해보겠습니다.

Redis는 키-값 기반의 인메모리 기반 데이터베이스 입니다.

메모리에 직접 저장이 되기에 껐다키면 날라가지만 인메모리 특성상 매우 좋은 성능을 제공합니다.

서버컴은 껏다 킬 일이 없으니..? jwt같은거 사용할 때 많이 사용 합니다.

 

우선 도커가 설치되어 있지 않다면 우분투에 도커부터 설치를 진행해야 합니다.

sudo apt install docker-ce

이후에는 가볍게 사용할 수 있는 Redis를 설치합니다.

docker run -i -t --name redis -p 6379:6379 redis:alpine

 

스프링부트에 레디스를 연동하려면 레디스의 ip 주소를 알아야 합니다.

만약 스프링부트를 그냥 돌리려고 한다면

spring:
  redis:
    port: 6379
    host: 127.0.0.1

yml 파일에 위와같이 호스트를 127.0.0.1로 설정하면 되지만

스프링부트 또한 도커이미지를 활용하여 돌아가게 된다면

redis가 사용되는 아이피 주소를 알아야 합니다.

docker inspect redis

IPAddress 를 확인 가능

저 ip주소를 써 주셔도 되고

아니면 우분투에서 자체적으로 있는

ip addr

명령어를 통해서도 확인이 가능합니다.

172.25.16.182 로 써주셔도 무방합니다.

 

자! Redis 설정은 끝났으니

 

스프링부트쪽 Redis 관련 기능을 추가해주시면 됩니다.

 

우선 build.gradle 에 라이브러리를 추가하겠습니다.

compile('org.springframework.boot:spring-boot-starter-data-redis')

 

// 로그아웃
    private final StringRedisTemplate redisTemplate;
    private final JwtTokenProvider jwtTokenProvider;
    @Transactional
    public ResponseEntity<?> logout(String jwt){
        ValueOperations<String, String> logoutValueOperations = redisTemplate.opsForValue();
        logoutValueOperations.set(jwt, jwt); // redis set 명령어
        ExampleUser exampleUser = (ExampleUser) jwtTokenProvider.getAuthentication(jwt).getPrincipal();
        log.info("로그아웃 유저 아이디 : '{}' , 유저 이름 : '{}'", exampleUser.getExampleUserId(), exampleUser.getUserLoginId());
        return new ResponseEntity<>(new DefaultResponseDto(200,"로그아웃 되었습니다."), HttpStatus.OK);
    }

이후에는 로그아웃 관련된 함수를 선언해줍니다.

간략하게 하기 위해서 key 와 value값을 같게 등록해주었습니다.

이후에 토큰이 들어왔을 경우에 키 값에 대해 매핑되는 데이터가 있다면 로그아웃으로 간주하면 되겠죠?

 

 

// 토큰의 유효성 + 만료일자 확인
    public boolean validateToken(String jwtToken) {
        try {
            Jws<Claims> claims = Jwts.parser().setSigningKey(tokenKey).parseClaimsJws(jwtToken);
            return !claims.getBody().getExpiration().before(new Date());
        } catch (Exception e) {
            return false;
        }
    }

(기존코드)

 

 

// 토큰의 유효성 + 만료일자 확인
    public boolean validateToken(String jwtToken) {
        try {
            Jws<Claims> claims = Jwts.parser().setSigningKey(tokenKey).parseClaimsJws(jwtToken);
            ValueOperations<String, String> logoutValueOperations = redisTemplate.opsForValue();
            if(logoutValueOperations.get(jwtToken) != null){
                log.info("로그아웃된 토큰 입니다.");
                return false;
            }
            return !claims.getBody().getExpiration().before(new Date());
        } catch (Exception e) {
            return false;
        }
    }

유효성 검증코드에 또한 4줄정도 추가하면 됩니다.

 

redis를 

 

 

Comments