diff --git a/src/main/java/com/wayble/server/common/config/security/jwt/JwtAuthentication.java b/src/main/java/com/wayble/server/common/config/security/jwt/JwtAuthentication.java index 924eb60b..48e264e8 100644 --- a/src/main/java/com/wayble/server/common/config/security/jwt/JwtAuthentication.java +++ b/src/main/java/com/wayble/server/common/config/security/jwt/JwtAuthentication.java @@ -5,14 +5,15 @@ import java.util.List; public class JwtAuthentication extends AbstractAuthenticationToken { - private final String email; + private final Long userId; - public JwtAuthentication(String email) { + + public JwtAuthentication(Long userId) { super(List.of(new SimpleGrantedAuthority("ROLE_USER"))); - this.email = email; + this.userId = userId; setAuthenticated(true); } @Override public Object getCredentials() { return ""; } - @Override public Object getPrincipal() { return email; } + @Override public Object getPrincipal() { return userId; } } \ No newline at end of file diff --git a/src/main/java/com/wayble/server/common/config/security/jwt/JwtAuthenticationFilter.java b/src/main/java/com/wayble/server/common/config/security/jwt/JwtAuthenticationFilter.java index 5e498596..c770a60f 100644 --- a/src/main/java/com/wayble/server/common/config/security/jwt/JwtAuthenticationFilter.java +++ b/src/main/java/com/wayble/server/common/config/security/jwt/JwtAuthenticationFilter.java @@ -26,10 +26,16 @@ protected void doFilterInternal(HttpServletRequest req, String token = header.substring(7); if (jwtProvider.validateToken(token)) { - String email = jwtProvider.getEmail(token); - var authentication = new JwtAuthentication(email); + Long userId = jwtProvider.getUserId(token); + var authentication = new JwtAuthentication(userId); SecurityContextHolder.getContext().setAuthentication(authentication); + } else { + // 토큰이 유효하지 않으면 Context 클리어 + SecurityContextHolder.clearContext(); } + } else { + // Authorization 헤더가 아예 없을 때도 Context 클리어 + SecurityContextHolder.clearContext(); } chain.doFilter(req, res); diff --git a/src/main/java/com/wayble/server/common/config/security/jwt/JwtTokenProvider.java b/src/main/java/com/wayble/server/common/config/security/jwt/JwtTokenProvider.java index ace9f67c..25227b3c 100644 --- a/src/main/java/com/wayble/server/common/config/security/jwt/JwtTokenProvider.java +++ b/src/main/java/com/wayble/server/common/config/security/jwt/JwtTokenProvider.java @@ -3,42 +3,54 @@ import com.wayble.server.common.config.security.JwtProperties; import io.jsonwebtoken.*; import io.jsonwebtoken.security.Keys; -import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; +import java.nio.charset.StandardCharsets; import java.security.Key; import java.util.Date; @Component -@RequiredArgsConstructor public class JwtTokenProvider { private final JwtProperties jwtProperties; + private final Key signingKey; - private Key getSigningKey() { - return Keys.hmacShaKeyFor(jwtProperties.getSecret().getBytes()); + public JwtTokenProvider(JwtProperties jwtProperties) { + this.jwtProperties = jwtProperties; + this.signingKey = Keys.hmacShaKeyFor( + jwtProperties.getSecret().getBytes(StandardCharsets.UTF_8) + ); } - public String generateToken(String email, String role) { + public String generateToken(Long userId, String role) { return Jwts.builder() - .setSubject(email) + .setSubject(String.valueOf(userId)) .claim("role", role) .setIssuedAt(new Date()) .setExpiration(new Date(System.currentTimeMillis() + jwtProperties.getAccessExp())) - .signWith(getSigningKey(), SignatureAlgorithm.HS256) + .signWith(signingKey, SignatureAlgorithm.HS256) .compact(); } public boolean validateToken(String token) { try { - Jwts.parserBuilder().setSigningKey(getSigningKey()).build().parseClaimsJws(token); + Jwts.parserBuilder().setSigningKey(signingKey).build().parseClaimsJws(token); return true; } catch (JwtException | IllegalArgumentException e) { return false; } } - public String getEmail(String token) { - return Jwts.parserBuilder().setSigningKey(getSigningKey()).build() - .parseClaimsJws(token).getBody().getSubject(); + // userId 파싱 메서드 추가 + public Long getUserId(String token) { + if (!validateToken(token)) { + throw new IllegalArgumentException("Invalid token"); + } + String subject = Jwts.parserBuilder() + .setSigningKey(signingKey) + .build() + .parseClaimsJws(token) + .getBody() + .getSubject(); + return Long.parseLong(subject); } -} +} \ No newline at end of file diff --git a/src/main/java/com/wayble/server/user/dto/UserLoginRequestDto.java b/src/main/java/com/wayble/server/user/dto/UserLoginRequestDto.java index 9ad1bd39..ee69eb23 100644 --- a/src/main/java/com/wayble/server/user/dto/UserLoginRequestDto.java +++ b/src/main/java/com/wayble/server/user/dto/UserLoginRequestDto.java @@ -1,7 +1,9 @@ package com.wayble.server.user.dto; +import com.wayble.server.user.entity.LoginType; import jakarta.validation.constraints.Email; import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; public record UserLoginRequestDto( @NotBlank(message = "이름 또는 닉네임은 필수입니다") @@ -12,5 +14,8 @@ public record UserLoginRequestDto( String email, @NotBlank(message = "비밀번호는 필수입니다") - String password + String password, + + @NotNull(message = "로그인 타입은 필수입니다") + LoginType loginType ) {} \ No newline at end of file diff --git a/src/main/java/com/wayble/server/user/entity/User.java b/src/main/java/com/wayble/server/user/entity/User.java index 1a19eefa..3b4e2085 100644 --- a/src/main/java/com/wayble/server/user/entity/User.java +++ b/src/main/java/com/wayble/server/user/entity/User.java @@ -18,7 +18,10 @@ @NoArgsConstructor(access = AccessLevel.PROTECTED) @SQLDelete(sql = "UPDATE user SET deleted_at = now() WHERE id = ?") @SQLRestriction("deleted_at IS NULL") -@Table(name = "user") +@Table( + name = "user", + uniqueConstraints = @UniqueConstraint(columnNames = {"email", "login_type"}) +) public class User extends BaseEntity { @Id @@ -30,7 +33,7 @@ public class User extends BaseEntity { private String username; - @Column(nullable = false, unique = true) + @Column(nullable = false) private String email; // TODO: 비밀번호 암호화 필요 diff --git a/src/main/java/com/wayble/server/user/repository/UserRepository.java b/src/main/java/com/wayble/server/user/repository/UserRepository.java index 4c9d32c8..b375ea87 100644 --- a/src/main/java/com/wayble/server/user/repository/UserRepository.java +++ b/src/main/java/com/wayble/server/user/repository/UserRepository.java @@ -1,5 +1,6 @@ package com.wayble.server.user.repository; +import com.wayble.server.user.entity.LoginType; import com.wayble.server.user.entity.User; import org.springframework.data.jpa.repository.JpaRepository; @@ -7,7 +8,6 @@ public interface UserRepository extends JpaRepository { - Optional findByEmail(String email); - - boolean existsByEmail(String email); + boolean existsByEmailAndLoginType(String email, LoginType loginType); + Optional findByEmailAndLoginType(String email, LoginType loginType); } diff --git a/src/main/java/com/wayble/server/user/service/UserService.java b/src/main/java/com/wayble/server/user/service/UserService.java index afbf2390..6aecdf8c 100644 --- a/src/main/java/com/wayble/server/user/service/UserService.java +++ b/src/main/java/com/wayble/server/user/service/UserService.java @@ -18,7 +18,7 @@ public class UserService { // 회원가입 public void signup(UserRegisterRequestDto req) { - if (userRepository.existsByEmail(req.email())) { + if (userRepository.existsByEmailAndLoginType(req.email(), req.loginType())) { throw new ApplicationException(UserErrorCase.USER_ALREADY_EXISTS); } User user = User.createUser( diff --git a/src/main/java/com/wayble/server/user/service/auth/AuthService.java b/src/main/java/com/wayble/server/user/service/auth/AuthService.java index 7e1bf049..3f9a1fa7 100644 --- a/src/main/java/com/wayble/server/user/service/auth/AuthService.java +++ b/src/main/java/com/wayble/server/user/service/auth/AuthService.java @@ -20,12 +20,12 @@ public class AuthService { private final JwtTokenProvider jwtProvider; public TokenResponseDto login(UserLoginRequestDto req) { - User user = userRepository.findByEmail(req.email()) + User user = userRepository.findByEmailAndLoginType(req.email(), req.loginType()) .orElseThrow(() -> new ApplicationException(UserErrorCase.INVALID_CREDENTIALS)); if (!encoder.matches(req.password(), user.getPassword())) { throw new ApplicationException(UserErrorCase.INVALID_CREDENTIALS); } - String token = jwtProvider.generateToken(user.getEmail(), user.getUserType().name()); + String token = jwtProvider.generateToken(user.getId(), user.getUserType().name()); return new TokenResponseDto(token); } }