Skip to content

Commit

Permalink
fix(#5) : DB refreshToken 칼럼 삭제, redis 사용
Browse files Browse the repository at this point in the history
  • Loading branch information
aeeazip committed Jul 5, 2023
1 parent 8165b1a commit 9221ff6
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 30 deletions.
3 changes: 3 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ dependencies {
implementation 'org.jsoup:jsoup:1.14.2'
implementation 'com.google.code.gson:gson:2.8.7'

// Redis
implementation 'org.springframework.boot:spring-boot-starter-data-redis'

compileOnly 'org.projectlombok:lombok'
runtimeOnly 'com.h2database:h2'
runtimeOnly 'com.mysql:mysql-connector-j'
Expand Down
41 changes: 41 additions & 0 deletions src/main/java/trothly/trothcam/config/RedisConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package trothly.trothcam.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.repository.configuration.EnableRedisRepositories;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
@EnableRedisRepositories
public class RedisConfig {

@Value("${spring.redis.host}")
private String redisHost;

@Value("${spring.redis.port}")
private int redisPort;

@Bean
public RedisConnectionFactory redisConnectionFactory() {
return new LettuceConnectionFactory(redisHost, redisPort);
}

@Bean
public RedisTemplate<String, String> redisTemplate() {
// redisTemplate를 받아와서 set, get, delete를 사용
RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();
/**
* setKeySerializer, setValueSerializer 설정
* redis-cli을 통해 직접 데이터를 조회 시 알아볼 수 없는 형태로 출력되는 것을 방지
*/
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new StringRedisSerializer());
redisTemplate.setConnectionFactory(redisConnectionFactory());

return redisTemplate;
}
}
14 changes: 0 additions & 14 deletions src/main/java/trothly/trothcam/domain/member/Member.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

import javax.persistence.*;
import javax.validation.constraints.Email;
import java.time.LocalDateTime;

@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
Expand All @@ -34,22 +33,9 @@ public class Member extends BaseTimeEntity {
@Enumerated(EnumType.STRING)
private Provider provider;

@Column(name = "refresh_token", nullable = false)
private String refreshToken;

@Column(name = "refresh_token_expires_at", nullable = false)
private LocalDateTime refreshTokenExpiresAt;

@Builder
private Member(String email, Provider provider) {
this.email = email;
this.provider = provider;
this.refreshToken = "";
this.refreshTokenExpiresAt = LocalDateTime.now();
}

public void updateRefreshToken(String refreshToken) {
this.refreshToken = refreshToken;
this.refreshTokenExpiresAt = LocalDateTime.now();
}
}
8 changes: 4 additions & 4 deletions src/main/java/trothly/trothcam/service/JwtService.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import io.jsonwebtoken.*;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
Expand All @@ -23,6 +24,7 @@ public class JwtService {

@Value("${jwt.secret}")
private String JWT_SECRET;
private final RedisTemplate<String, String> redisTemplate;
private final MemberRepository memberRepository;

public String encodeJwtToken(TokenDto tokenDto) {
Expand Down Expand Up @@ -103,11 +105,9 @@ public Boolean validateRefreshToken(String token) {

// 유저 리프레쉬 토큰 확인
Long memberId = getMemberIdFromJwtToken(token);
String redisRefreshToken = redisTemplate.opsForValue().get(memberId.toString());

Member member = memberRepository.findById(memberId)
.orElseThrow(()-> new IllegalArgumentException("해당되는 사용자를 찾을 수 없습니다."));

if(member.getRefreshToken().equals(token)){
if(redisRefreshToken.equals(token)){
return true;
}
return false;
Expand Down
30 changes: 21 additions & 9 deletions src/main/java/trothly/trothcam/service/auth/OAuthService.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import trothly.trothcam.dto.auth.TokenDto;
import trothly.trothcam.dto.auth.apple.LoginReqDto;
Expand All @@ -16,6 +18,7 @@
import trothly.trothcam.service.JwtService;

import java.util.Optional;
import java.util.concurrent.TimeUnit;

@Service
@RequiredArgsConstructor
Expand All @@ -24,6 +27,7 @@ public class OAuthService {
private final AppleOAuthUserProvider appleOAuthUserProvider;

private final MemberRepository memberRepository;
private final RedisTemplate<String, String> redisTemplate;
private final JwtService jwtService;


Expand Down Expand Up @@ -59,28 +63,36 @@ public LoginResDto appleLogin(LoginReqDto loginReqDto) throws BaseException {
logger.info("accessToken : " + newAccessToken);
logger.info("refreshToken : " + newRefreshToken);

member.updateRefreshToken(newRefreshToken);
memberRepository.save(member);
// redis에 refreshToken 저장
try {
redisTemplate.opsForValue().set(newRefreshToken, member.getId().toString(), 14L, TimeUnit.SECONDS);
} catch(Exception e) {
e.printStackTrace();
}

// Redis에 저장 (key: userId, value: refreshToken)
return new LoginResDto(newAccessToken, newRefreshToken);
}

// refreshToken으로 accessToken 발급하기
public LoginResDto regenerateAccessToken(RefreshTokenReqDto refreshTokenReqDto) throws BaseException {
Long memberId = refreshTokenReqDto.getMemberId();
Member member = memberRepository.findById(memberId)
.orElseThrow(() -> new IllegalArgumentException("해당되는 member_id를 찾을 수 없습니다."));

String refreshToken = refreshTokenReqDto.getRefreshToken();
if(refreshToken.equals(member.getRefreshToken()))
String getRefreshToken = refreshTokenReqDto.getRefreshToken();
String redisRefreshToken = redisTemplate.opsForValue().get(memberId.toString());

if(getRefreshToken.equals(redisRefreshToken))
throw new InvalidTokenException("유효하지 않은 Refresh Token입니다.");

String newRefreshToken = jwtService.encodeJwtRefreshToken(memberId);
String newAcessToken = jwtService.encodeJwtToken(new TokenDto(memberId));

member.updateRefreshToken(newRefreshToken);
memberRepository.save(member);

try {
redisTemplate.opsForValue().set(newRefreshToken, memberId.toString(), 14L, TimeUnit.SECONDS);
logger.info("성공");
} catch(Exception e) {
e.printStackTrace();
}
return new LoginResDto(newAcessToken, newRefreshToken);
}
}
6 changes: 3 additions & 3 deletions src/main/resources/application-local.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ spring:
default_batch_fetch_size: 1000
show-sql: true

# redis:
# host: localhost
# port: 6379
redis:
host: localhost
port: 6379

config:
activate:
Expand Down

0 comments on commit 9221ff6

Please sign in to comment.