Merge branch 'dev' into main
This commit is contained in:
@@ -14,4 +14,7 @@ public class LoginRequest {
|
|||||||
|
|
||||||
@NotBlank(message = "비밀번호를 입력하세요.")
|
@NotBlank(message = "비밀번호를 입력하세요.")
|
||||||
private String password;
|
private String password;
|
||||||
|
|
||||||
|
/** 로그인 상태 유지(자동 로그인). true 면 세션을 길게(30일) 유지 */
|
||||||
|
private boolean rememberMe;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ public class SessionUser implements Serializable {
|
|||||||
private String name;
|
private String name;
|
||||||
private String role;
|
private String role;
|
||||||
private String provider;
|
private String provider;
|
||||||
|
private boolean rememberMe; // 자동 로그인 세션 여부 (슬라이딩 만료 TTL 결정용)
|
||||||
|
|
||||||
public static SessionUser from(Member m) {
|
public static SessionUser from(Member m) {
|
||||||
return SessionUser.builder()
|
return SessionUser.builder()
|
||||||
|
|||||||
@@ -36,7 +36,8 @@ public class AuthService {
|
|||||||
private final RedisTemplate<String, Object> redisTemplate;
|
private final RedisTemplate<String, Object> redisTemplate;
|
||||||
|
|
||||||
private static final String SESSION_PREFIX = "session:";
|
private static final String SESSION_PREFIX = "session:";
|
||||||
private static final Duration SESSION_TTL = Duration.ofMinutes(60);
|
private static final Duration SESSION_TTL = Duration.ofMinutes(60); // 일반 세션
|
||||||
|
private static final Duration REMEMBER_TTL = Duration.ofDays(30); // 자동 로그인(로그인 상태 유지)
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public MemberResponse signup(SignupRequest req) {
|
public MemberResponse signup(SignupRequest req) {
|
||||||
@@ -68,13 +69,17 @@ public class AuthService {
|
|||||||
throw new ApiException(HttpStatus.FORBIDDEN, "사용할 수 없는 계정입니다.");
|
throw new ApiException(HttpStatus.FORBIDDEN, "사용할 수 없는 계정입니다.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Duration ttl = req.isRememberMe() ? REMEMBER_TTL : SESSION_TTL;
|
||||||
|
SessionUser session = SessionUser.from(member);
|
||||||
|
session.setRememberMe(req.isRememberMe());
|
||||||
|
|
||||||
String token = UUID.randomUUID().toString().replace("-", "");
|
String token = UUID.randomUUID().toString().replace("-", "");
|
||||||
redisTemplate.opsForValue().set(SESSION_PREFIX + token, SessionUser.from(member), SESSION_TTL);
|
redisTemplate.opsForValue().set(SESSION_PREFIX + token, session, ttl);
|
||||||
log.info("[login] {} (token issued)", member.getLoginId());
|
log.info("[login] {} (token issued, rememberMe={})", member.getLoginId(), req.isRememberMe());
|
||||||
|
|
||||||
return LoginResponse.builder()
|
return LoginResponse.builder()
|
||||||
.token(token)
|
.token(token)
|
||||||
.expiresInSeconds(SESSION_TTL.getSeconds())
|
.expiresInSeconds(ttl.getSeconds())
|
||||||
.member(MemberResponse.from(member))
|
.member(MemberResponse.from(member))
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
@@ -89,7 +94,8 @@ public class AuthService {
|
|||||||
String key = SESSION_PREFIX + token;
|
String key = SESSION_PREFIX + token;
|
||||||
Object cached = redisTemplate.opsForValue().get(key);
|
Object cached = redisTemplate.opsForValue().get(key);
|
||||||
if (cached instanceof SessionUser user) {
|
if (cached instanceof SessionUser user) {
|
||||||
redisTemplate.expire(key, SESSION_TTL);
|
// 슬라이딩 만료: 자동 로그인 세션이면 길게(30일), 아니면 60분으로 갱신
|
||||||
|
redisTemplate.expire(key, user.isRememberMe() ? REMEMBER_TTL : SESSION_TTL);
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
Reference in New Issue
Block a user