redis는 우선, 깔려 있어야 쓸 수 있다.
아마도 배포할 때 그 환경에도 깔아야 할 것이다.
spring:
data:
redis:
host: localhost
port: 6379
설정은 이렇게
@Configuration
public class RedisConfig {
@Value("${spring.data.redis.host}")
private String host;
@Value("${spring.data.redis.port}")
private int port;
@Bean
public RedisConnectionFactory redisConnectionFactory(){
return new LettuceConnectionFactory(host, port);
}
@Bean
public RedisTemplate<String, LoginMember> redisTemplate(){
// https://developer-nyong.tistory.com/21#article-2-1--refreshtoken
RedisTemplate<String, LoginMember> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory());
Jackson2JsonRedisSerializer<LoginMember> serializer = new Jackson2JsonRedisSerializer<>(LoginMember.class);
redisTemplate.setDefaultSerializer(serializer);
redisTemplate.setKeySerializer(serializer);
redisTemplate.setValueSerializer(serializer);
return redisTemplate;
}
}
환경도 구성 해 주고,
레디스 커넥션 팩토리 저게 커넥션 풀 같은건가 보다.
저 serializer는 직렬화인데, 저렇게 해야 쓸 수 있나보다.
뭔가 오브젝트 그 자체로 저장한다기 보다는,
redis가 in memory db인데, 저렇게 뭔가 String 같이 직렬화 해서 써야 하나 보다.
저렇게 대충 셋팅 해 주고,
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@RedisHash
public class LoginMember implements Serializable {
@Id
private String sessionId;
private MemberInfoDto memberInfoDto;
@TimeToLive
private long ttl;
public LoginMember(String sessionId,MemberInfoDto memberInfoDto, long ttl) {
this.sessionId = sessionId;
this.memberInfoDto = memberInfoDto;
this.ttl = ttl;
}
}
이렇게 @RedisHash 붙이고 in memory db 답게 JpaRepository 처럼 쓸 수 있다.
@Id가 그 id이다.
@TimeToLive가 살아있을 수 있는 시간이다.
그런데 이거는 처음 들어간 값만 적용이 된다. 딱 그상태로 구워진 다고 생각하면 된다.
@Id 이거는 생성자 저기에 값이 들어오면 그 들어온 값으로 쓰고, 안 들어오면 알아서 지정을 해 주는 것 같다.
public interface LoginMemberRepository extends CrudRepository<LoginMember, String> {
Optional<LoginMember> findBySessionId(String sessionId);
}
이거는 JpaRepository 말고 CrudRepository.
JpaRepository는 저걸 상속받은 거임.
여튼 저거 쓰면, JpaRepository처럼 사용이 가능함.
@Service
@Slf4j
public class LoginMemberService {
private final LoginMemberRepository loginMemberRepository;
public static final String SESSION_COOKIE_NAME = "sessionId";
private static final int SESSION_EXPIRATION_TIME = 1800;
public LoginMemberService(LoginMemberRepository loginMemberRepository) {
this.loginMemberRepository = loginMemberRepository;
}
public LoginSessionDto createSession(MemberInfoDto memberInfoDto, HttpServletResponse response){
String sessionId = UUID.randomUUID().toString();
LoginMember loginMember = new LoginMember(sessionId, memberInfoDto, SESSION_EXPIRATION_TIME);
loginMemberRepository.save(loginMember);
ResponseCookie.ResponseCookieBuilder cookieBuilder = from(SESSION_COOKIE_NAME, sessionId);
cookieBuilder.maxAge(SESSION_EXPIRATION_TIME);
cookieBuilder.secure(true);
cookieBuilder.sameSite("None");
cookieBuilder.path("/");
cookieBuilder.domain("127.0.0.1");
log.info("쿠키생성");
response.addHeader("Set-Cookie", cookieBuilder.build().toString());
log.info("cookie: {}",cookieBuilder.build().toString());
return new LoginSessionDto(sessionId, true);
}
public Optional<MemberInfoDto> getMemberInfoBySessionId(String sessionId, HttpServletResponse response){
Optional<LoginMember> findLoginMember = loginMemberRepository.findById(sessionId);
if(findLoginMember.isPresent()){
LoginMember extractLoginMember = findLoginMember.get();
LoginMember newLoginMember = new LoginMember(extractLoginMember.getSessionId(), extractLoginMember.getMemberInfoDto(), SESSION_EXPIRATION_TIME);
expire(extractLoginMember.getSessionId());
loginMemberRepository.save(newLoginMember);
updateCookieTime(sessionId, SESSION_EXPIRATION_TIME, response);
return Optional.of(findLoginMember.get().getMemberInfoDto());
}
return Optional.empty();
}
public void expireAll(String sessionId, HttpServletResponse response){
if(sessionId == null) return;
loginMemberRepository.deleteById(sessionId);
expireCookie(response, sessionId);
}
private void expire(String sessionId){
loginMemberRepository.deleteById(sessionId);
}
private void expireCookie(HttpServletResponse response, String sessionId){
updateCookieTime(sessionId, 0, response);
}
private static void updateCookieTime(String sessionId, int maxAgeSeconds, HttpServletResponse response) {
ResponseCookie.ResponseCookieBuilder cookieBuilder = from(SESSION_COOKIE_NAME, sessionId);
cookieBuilder.maxAge(maxAgeSeconds);
cookieBuilder.secure(true);
cookieBuilder.sameSite("None");
cookieBuilder.path("/");
response.addHeader("Set-Cookie", cookieBuilder.build().toString());
}
}
보면 JpaRepository 쓰듯이 자동으로 만들어 진 것을 쓰고 있다. 그걸로 잘 하면 된다.