[Feature] SpringSecurity 및 소셜로그인 구현#148
Merged
Kimgyuilli merged 48 commits intodevelopfrom Jan 28, 2026
Merged
Conversation
Closed
Kimgyuilli
commented
Jan 26, 2026
src/main/java/com/sopt/cherrish/domain/auth/application/service/AuthService.java
Show resolved
Hide resolved
|
ㅏㅏㅏㅏ 진짜 바로 소설 로그인을;;; |
…TEAM-Cherrish/Cherrish-Server into 145-feature/spring-security-jwt t # Please enter a commit message to explain why this merge is necessary,
There was a problem hiding this comment.
Actionable comments posted: 6
🤖 Fix all issues with AI agents
In @.env.example:
- Line 1: Remove the corrupted characters at the start of the first line so the
header reads a clean ASCII comment (replace "프롲# Database Configuration" with "#
Database Configuration"); locate the exact malformed string "프롲# Database
Configuration" and trim the non-ASCII prefix so dotenv parsers won't
misinterpret the line or produce key-value parsing errors.
In
`@src/main/java/com/sopt/cherrish/domain/auth/application/service/AuthService.java`:
- Around line 131-140: In logout(Long userId, String authorizationHeader) you
currently add the access token to the blacklist regardless of TTL; change the
logic to only call accessTokenBlacklistRepository.add(accessToken,
remainingExpiration) when accessToken != null AND remainingExpiration > 0 (use
jwtTokenProvider.getRemainingExpiration(accessToken) to compute
remainingExpiration) so expired tokens (remainingExpiration <= 0) are not added
after refreshTokenRepository.deleteByUserId(userId).
- Around line 69-77: AuthService currently saves a new User (in the isNewUser
branch using User.builder and userRepository.save) without handling the unique
email constraint, which can throw DataIntegrityViolationException when
socialUserInfo.email() already exists; update the logic to first check
userRepository.existsByEmail(socialUserInfo.email()) and, if true, handle
according to business rules (e.g., link accounts, return a clear error
response), or wrap the userRepository.save(...) call in a try/catch for
DataIntegrityViolationException to return a controlled error, ensuring the fix
references the isNewUser branch, User.builder, socialUserInfo.email(), and
userRepository.save.
In
`@src/main/java/com/sopt/cherrish/domain/auth/infrastructure/jwt/JwtTokenProvider.java`:
- Around line 154-163: The getRemainingExpiration method in JwtTokenProvider
currently swallows all exceptions and returns 0; change it to catch only
expected JWT parsing exceptions (e.g., io.jsonwebtoken.JwtException and
IllegalArgumentException thrown by parseClaims) and return 0 for those, while
logging and rethrowing or returning a conservative value for unexpected
exceptions so they aren't silently ignored; reference the getRemainingExpiration
and parseClaims methods and ensure unexpected exceptions are logged via your
logger (or rethrown) instead of being swallowed.
- Around line 41-45: In JwtTokenProvider.init(), validate the decoded secret key
length before creating the SecretKey: decode jwtProperties.getSecretKey() into
keyBytes, check keyBytes.length >= 32 (256 bits) and if not throw a clear
IllegalStateException (or log and exit) describing that the configured secret
key is too short for HMAC-SHA (include the actual byte length and guidance to
use a 256-bit+ Base64 key); only then call Keys.hmacShaKeyFor(keyBytes) to
assign this.secretKey, and optionally catch and rethrow any
Decoders.BASE64.decode errors with a descriptive message so startup failures are
explicit.
In `@src/test/java/com/sopt/cherrish/domain/user/fixture/UserFixture.java`:
- Around line 17-19: Add a public reset hook to UserFixture that clears the
static counters to avoid test order dependence: provide a method like
resetCounters() (or two methods resetIdCounter() and resetSocialIdCounter())
that sets ID_COUNTER and SOCIAL_ID_COUNTER back to 1 (or new AtomicLong(1)), and
call this from tests that need a clean state; update references to ID_COUNTER
and SOCIAL_ID_COUNTER in UserFixture factory methods to keep behavior unchanged.
♻️ Duplicate comments (1)
src/main/java/com/sopt/cherrish/global/config/SecurityConfig.java (1)
73-79: CORS에서*+ credentials 조합은 여전히 위험합니다.
allowedOriginPatterns("*")와allowCredentials(true)를 함께 쓰면 모든 출처가 인증 정보를 포함한 요청을 보낼 수 있습니다. 프로덕션에서는 허용 도메인 목록을 명시하거나 환경별 설정으로 주입해 제한해 주세요. (이전 리뷰와 동일 이슈입니다.)#!/bin/bash # CORS 허용 도메인 설정이 이미 존재하는지 확인 rg -n --glob 'application*.yml' --glob 'application*.yaml' 'cors|allowedOrigin|allowedOrigins|allowedOriginPatterns'
src/main/java/com/sopt/cherrish/domain/auth/application/service/AuthService.java
Show resolved
Hide resolved
src/main/java/com/sopt/cherrish/domain/auth/application/service/AuthService.java
Show resolved
Hide resolved
src/main/java/com/sopt/cherrish/domain/auth/infrastructure/jwt/JwtTokenProvider.java
Show resolved
Hide resolved
src/main/java/com/sopt/cherrish/domain/auth/infrastructure/jwt/JwtTokenProvider.java
Show resolved
Hide resolved
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Fix all issues with AI agents
In @.env.example:
- Around line 8-17: The example JWT_SECRET_KEY in .env.example doesn't meet the
JwtTokenProvider's Base64 decode and minimum 32-byte requirement; update the
.env.example to either provide a valid Base64-encoded key of at least 32 bytes
(so JwtTokenProvider can successfully Base64.decode and validate) or add a clear
comment next to JWT_SECRET_KEY describing the requirement (Base64 format and
minimum length) so users supply a correct secret.
In
`@src/main/java/com/sopt/cherrish/domain/auth/infrastructure/jwt/JwtTokenProvider.java`:
- Around line 138-152: isAccessToken()와 isRefreshToken()가 parseClaims(token) 호출
시 발생할 수 있는 ExpiredJwtException, UnsupportedJwtException, MalformedJwtException 등
JWT 관련 예외를 처리하지 않으므로, 각 메서드에서 parseClaims 호출을 try-catch로 감싸고 Jwt 예외들을 모두 잡아
AuthException(INVALID_TOKEN)으로 명시적으로 변환해 던지도록 수정하세요; 구체적으로 JwtTokenProvider의
isAccessToken 및 isRefreshToken 내부에서 parseClaims(token) 호출을 try { Claims claims =
parseClaims(token); ... } catch (JwtException | IllegalArgumentException e) {
throw new AuthException(INVALID_TOKEN); } 형태로 처리해 암묵적 계약에 의존하지 않도록 만드세요.
In `@src/main/java/com/sopt/cherrish/domain/user/domain/model/User.java`:
- Around line 39-40: The User entity currently marks socialId as globally
unique; change this to a composite unique constraint on (socialProvider,
socialId) instead: remove unique = true from the socialId `@Column`, add a
`@Table`(uniqueConstraints = `@UniqueConstraint`(columnNames = {"social_provider",
"social_id"})) on the User class (or equivalent names used in your mapping), and
ensure the field names/socialProvider and socialId match the column names in the
constraint; update any DB migration/schema generation to reflect the new
composite unique constraint.
src/main/java/com/sopt/cherrish/domain/auth/infrastructure/jwt/JwtTokenProvider.java
Show resolved
Hide resolved
src/main/java/com/sopt/cherrish/domain/user/domain/model/User.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In @.env.example:
- Around line 16-17: Add a short explanatory comment above the APPLE_CLIENT_ID
placeholder that explains what value to provide and where to obtain it (e.g.,
the Apple Developer account / Services ID or Bundle ID used for Sign in with
Apple), and note the expected format (reverse-DNS bundle identifier) so
less-experienced developers understand how to populate APPLE_CLIENT_ID.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🛠 Related issue 🛠
✏️ Work Description ✏️
/v2/user/meAPI 호출하여 사용자 정보 조회refresh_token:{userId})blacklist:{token})POST /api/auth/login- 소셜 로그인POST /api/auth/refresh- 토큰 재발급POST /api/auth/logout- 로그아웃 (RT 삭제 + AT 블랙리스트)socialProvider(KAKAO, APPLE)socialId(소셜 플랫폼 고유 ID)emailSecurityConfig- Spring Security 필터 체인JwtAuthenticationFilter- JWT 검증 필터JwtAuthenticationEntryPoint- 401 처리JwtAccessDeniedHandler- 403 처리@CurrentUser- 현재 사용자 주입 어노테이션📸 Screenshot 📸
😅 Uncompleted Tasks 😅
@RequestHeader("X-User-Id")→@CurrentUser UserPrincipal변경 (별도 PR 예정)📢 To Reviewers 📢
application-auth.yaml에JWT_SECRET_KEY,APPLE_CLIENT_ID환경변수 설정 필요application-redis.yaml에REDIS_HOST,REDIS_PORT,REDIS_PASSWORD환경변수 설정 필요