[FEAT] 소셜 로그인 API및 Security, JWT#41
Conversation
|
Warning Review limit reached
Next review available in: 46 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthrough소셜 로그인 API와 인증 DTO를 추가하고, mock 사용자 기반 JWT 발급 및 Bearer 토큰 인증 흐름을 구성했습니다. 무상태 보안 설정, CORS, 401·403 응답, 사용자 ID 조회 유틸리티와 JWT 설정 예시도 포함됩니다. Changes인증 흐름
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant Client
participant AuthController
participant AuthService
participant JwtTokenProvider
participant JwtAuthenticationFilter
participant SecurityContextHolder
Client->>AuthController: 소셜 로그인 요청
AuthController->>AuthService: socialLogin(socialType, accessToken)
AuthService->>JwtTokenProvider: access/refresh JWT 생성
JwtTokenProvider-->>AuthService: JWT 반환
AuthService-->>Client: ApiResponse<LoginResponse>
Client->>JwtAuthenticationFilter: Bearer JWT 요청
JwtAuthenticationFilter->>JwtTokenProvider: access token 검증 및 인증 조회
JwtTokenProvider-->>SecurityContextHolder: Authentication 설정
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 7
🧹 Nitpick comments (6)
src/main/java/com/mr/global/security/jwt/JwtAuthenticationEntryPoint.java (1)
18-18: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win직접 생성한
ObjectMapper대신 Spring이 관리하는 Bean을 주입하세요.
new ObjectMapper()는 프로젝트 전역에서 설정된 Jackson 모듈(예:JavaTimeModule, 네이밍 전략 등)을 반영하지 않아, 다른 컨트롤러 응답과 직렬화 형식이 달라질 수 있습니다. 생성자 주입으로 교체하는 것을 권장합니다.+import lombok.RequiredArgsConstructor; + `@Component` +@RequiredArgsConstructor public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint { - private final ObjectMapper objectMapper = new ObjectMapper(); + private final ObjectMapper objectMapper;🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/main/java/com/mr/global/security/jwt/JwtAuthenticationEntryPoint.java` at line 18, Replace the directly instantiated ObjectMapper field in JwtAuthenticationEntryPoint with constructor injection of the Spring-managed ObjectMapper bean, removing the new ObjectMapper() initialization so shared Jackson modules and serialization settings are used.src/main/java/com/mr/global/security/jwt/JwtAuthenticationFilter.java (1)
38-44: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win매직 넘버 대신
BEARER_PREFIX.length()를 사용하세요.지금은
"Bearer "가 7글자라 우연히 맞지만, 상수 값이 바뀌면 잘라내는 위치가 틀어집니다.- return bearerToken.substring(7); + return bearerToken.substring(BEARER_PREFIX.length());🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/main/java/com/mr/global/security/jwt/JwtAuthenticationFilter.java` around lines 38 - 44, Update resolveToken to derive the substring start index from BEARER_PREFIX.length() instead of the hardcoded 7, while preserving the existing authorization-header validation and token extraction behavior.src/main/java/com/mr/global/config/SwaggerConfig.java (1)
1-4: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value빈 클래스, 현재는 아무 역할도 하지 않습니다.
@Configuration애노테이션도 없고 OpenAPI Bean 정의도 없어 Spring이 이 클래스를 아예 로드하지 않습니다. 이번 PR이 소셜 로그인 인프라 뼈대 구축 단계라 후속 커밋에서 채워질 스텁으로 보이지만, 그렇다면 TODO 주석을 남겨두면 의도를 명확히 전달할 수 있습니다.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/main/java/com/mr/global/config/SwaggerConfig.java` around lines 1 - 4, SwaggerConfig 빈 클래스에 후속 구현 예정임을 나타내는 TODO 주석을 추가하세요. 현재 클래스 구조와 패키지는 유지하고, OpenAPI Bean이나 `@Configuration` 애노테이션 등 범위를 벗어난 변경은 하지 마세요.src/main/java/com/mr/global/security/jwt/JwtTokenProvider.java (2)
27-31: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value필드명과 실제 저장값이 어긋나 있습니다.
accessTokenValidityInMilliseconds/refreshTokenValidityInMilliseconds는 실제로는jwt.*-validity-in-seconds프로퍼티(초 단위) 값을 그대로 담고, ms 변환은 사용 시점(Line 44, 57)에서만 일어납니다. 네이밍을...InSeconds로 바꾸는 편이 명확합니다.덧붙여,
AuthService(연관 레이어)에서tokenExpirationTime을3600L로 하드코딩하고 있는데, 이 필드에 대한 getter를 제공하면 실제 설정값과 응답이 항상 일치하게 만들 수 있습니다.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/main/java/com/mr/global/security/jwt/JwtTokenProvider.java` around lines 27 - 31, Rename the JwtTokenProvider fields accessTokenValidityInMilliseconds and refreshTokenValidityInMilliseconds to accessTokenValidityInSeconds and refreshTokenValidityInSeconds, updating all references while preserving the existing conversion to milliseconds at use sites. Expose a getter for the configured access-token validity so AuthService can use it instead of hardcoding tokenExpirationTime as 3600L.
41-65: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAccess/Refresh 토큰 생성 로직 중복 제거를 고려해보세요.
두 메서드가 만료시간만 다르고 나머지 로직은 동일합니다. 만료 기간을 파라미터로 받는 private 헬퍼로 통합하면 유지보수성이 좋아집니다.
♻️ 제안 리팩터링
- public String createAccessToken(Long userId) { - Claims claims = Jwts.claims().setSubject(String.valueOf(userId)); - Date now = new Date(); - Date validity = new Date(now.getTime() + accessTokenValidityInMilliseconds * 1000); - - return Jwts.builder() - .setClaims(claims) - .setIssuedAt(now) - .setExpiration(validity) - .signWith(key, SignatureAlgorithm.HS256) - .compact(); - } - - public String createRefreshToken(Long userId) { - Claims claims = Jwts.claims().setSubject(String.valueOf(userId)); - Date now = new Date(); - Date validity = new Date(now.getTime() + refreshTokenValidityInMilliseconds * 1000); - - return Jwts.builder() - .setClaims(claims) - .setIssuedAt(now) - .setExpiration(validity) - .signWith(key, SignatureAlgorithm.HS256) - .compact(); - } + public String createAccessToken(Long userId) { + return createToken(userId, accessTokenValidityInMilliseconds); + } + + public String createRefreshToken(Long userId) { + return createToken(userId, refreshTokenValidityInMilliseconds); + } + + private String createToken(Long userId, long validityInSeconds) { + Date now = new Date(); + Date validity = new Date(now.getTime() + validityInSeconds * 1000); + + return Jwts.builder() + .setSubject(String.valueOf(userId)) + .setIssuedAt(now) + .setExpiration(validity) + .signWith(key, SignatureAlgorithm.HS256) + .compact(); + }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/main/java/com/mr/global/security/jwt/JwtTokenProvider.java` around lines 41 - 65, Refactor the duplicated token-building logic in createAccessToken and createRefreshToken into a private helper that accepts the token validity duration as a parameter. Keep each public method responsible for supplying its respective access or refresh validity value, while preserving the existing claims, timestamps, signing algorithm, and expiration behavior.src/main/java/com/mr/global/security/SecurityConfig.java (1)
35-39: 🔒 Security & Privacy | 🔵 Trivial | 💤 Low value
/api/v1/auth/**permitAll 범위, 확장 시 주의가 필요합니다.현재는 로그인 엔드포인트만 있어 괜찮지만, 나중에 로그아웃·토큰 재발급처럼 인증이 필요한 경로가
/api/v1/auth/**하위에 추가되면 의도치 않게 무인증 접근이 허용될 수 있습니다. 필요한 경로만 명시적으로 나열하는 방식으로 점진적으로 좁혀가는 것을 권장합니다.참고로
new JwtAuthenticationFilter(jwtTokenProvider)처럼 직접 생성하는 대신@Bean으로 등록하면 다른 시큐리티 설정과 일관성을 유지하기 좋습니다.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/main/java/com/mr/global/security/SecurityConfig.java` around lines 35 - 39, In SecurityConfig’s authorizeHttpRequests configuration, replace the broad /api/v1/auth/** permitAll matcher with explicit matchers for only the currently public login endpoint, leaving protected authentication-related endpoints inaccessible by default. Do not broaden the change to JwtAuthenticationFilter registration unless separately required.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/main/java/com/mr/domain/auth/service/AuthService.java`:
- Around line 34-38: Update the token response construction in AuthService to
derive tokenExpirationTime from the same configured access-token validity used
by JwtTokenProvider instead of the hardcoded 3600L. Expose or reuse the
provider’s actual TTL, ensure the response unit is explicitly consistent with
the API contract, and keep the returned expiration synchronized when JWT
settings change.
- Around line 20-32: Update
src/main/java/com/mr/domain/auth/service/AuthService.java:20-32 in socialLogin
to validate the provider accessToken, resolve or create the corresponding
SocialAuth/User, and only then populate the response and generate JWTs using the
real user ID and attributes; remove all mock identity values. Update
src/main/java/com/mr/global/security/principal/CustomUserDetailsService.java:12-16
in loadUserByUsername to look up the user through UserRepository.findById and
throw the appropriate authentication exception when absent, preserving real
authorities and user identity throughout JWT authentication.
In `@src/main/java/com/mr/global/security/jwt/JwtTokenProvider.java`:
- Around line 84-90: Update parseClaims in JwtTokenProvider so expired JWTs
cannot produce usable claims by default; remove the ExpiredJwtException recovery
that returns e.getClaims(), or enforce that parseClaims is only reached after
validateToken. If retaining expired-claim access is required for a refresh flow,
document that intent explicitly and keep it isolated from authentication-token
creation.
- Around line 67-73: Update JwtTokenProvider.getAuthentication to obtain
UserDetails from the configured user-details repository instead of constructing
CustomUserDetails with fixed email and role values. Reuse the existing
UserDetailsService.loadUserByUsername(...) path with the token’s userId, then
create UsernamePasswordAuthenticationToken using the loaded user’s authorities.
- Around line 41-82: Distinguish access and refresh tokens by adding a purpose
claim in createAccessToken and createRefreshToken, using the corresponding
access or refresh value. Update validateToken and the authentication flow around
getAuthentication to require and accept only the access-token type for API
authorization, while refresh-token handling validates only the refresh type
through its dedicated path. Preserve the existing subject, expiry, and signature
behavior.
In
`@src/main/java/com/mr/global/security/principal/CustomUserDetailsService.java`:
- Around line 12-16: Update CustomUserDetailsService.loadUserByUsername() to
load the user by the parsed subject through userRepository, throw
UsernameNotFoundException when absent, and construct CustomUserDetails from the
user’s active status and actual authorities instead of hard-coded values. Update
JwtTokenProvider.getAuthentication() to resolve authentication via
UserDetailsService so valid JWTs still undergo user existence, status, and
permission checks before access is granted.
In `@src/main/java/com/mr/global/security/SecurityUtil.java`:
- Around line 16-24: Update the authentication validation in SecurityUtil to
throw CommonStatus.UNAUTHORIZED when authentication is missing, has no name, or
represents anonymousUser; keep INVALID_INPUT_VALUE for non-numeric authenticated
names unless the existing authentication failure handling requires otherwise.
---
Nitpick comments:
In `@src/main/java/com/mr/global/config/SwaggerConfig.java`:
- Around line 1-4: SwaggerConfig 빈 클래스에 후속 구현 예정임을 나타내는 TODO 주석을 추가하세요. 현재 클래스
구조와 패키지는 유지하고, OpenAPI Bean이나 `@Configuration` 애노테이션 등 범위를 벗어난 변경은 하지 마세요.
In `@src/main/java/com/mr/global/security/jwt/JwtAuthenticationEntryPoint.java`:
- Line 18: Replace the directly instantiated ObjectMapper field in
JwtAuthenticationEntryPoint with constructor injection of the Spring-managed
ObjectMapper bean, removing the new ObjectMapper() initialization so shared
Jackson modules and serialization settings are used.
In `@src/main/java/com/mr/global/security/jwt/JwtAuthenticationFilter.java`:
- Around line 38-44: Update resolveToken to derive the substring start index
from BEARER_PREFIX.length() instead of the hardcoded 7, while preserving the
existing authorization-header validation and token extraction behavior.
In `@src/main/java/com/mr/global/security/jwt/JwtTokenProvider.java`:
- Around line 27-31: Rename the JwtTokenProvider fields
accessTokenValidityInMilliseconds and refreshTokenValidityInMilliseconds to
accessTokenValidityInSeconds and refreshTokenValidityInSeconds, updating all
references while preserving the existing conversion to milliseconds at use
sites. Expose a getter for the configured access-token validity so AuthService
can use it instead of hardcoding tokenExpirationTime as 3600L.
- Around line 41-65: Refactor the duplicated token-building logic in
createAccessToken and createRefreshToken into a private helper that accepts the
token validity duration as a parameter. Keep each public method responsible for
supplying its respective access or refresh validity value, while preserving the
existing claims, timestamps, signing algorithm, and expiration behavior.
In `@src/main/java/com/mr/global/security/SecurityConfig.java`:
- Around line 35-39: In SecurityConfig’s authorizeHttpRequests configuration,
replace the broad /api/v1/auth/** permitAll matcher with explicit matchers for
only the currently public login endpoint, leaving protected
authentication-related endpoints inaccessible by default. Do not broaden the
change to JwtAuthenticationFilter registration unless separately required.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 0a55337c-ca05-4a97-ac3f-7bf981fd717b
📒 Files selected for processing (14)
src/main/java/com/mr/domain/auth/controller/AuthController.javasrc/main/java/com/mr/domain/auth/dto/AuthRequestDTO.javasrc/main/java/com/mr/domain/auth/dto/AuthResponseDTO.javasrc/main/java/com/mr/domain/auth/service/AuthService.javasrc/main/java/com/mr/global/config/SecurityConfig.javasrc/main/java/com/mr/global/config/SwaggerConfig.javasrc/main/java/com/mr/global/security/SecurityConfig.javasrc/main/java/com/mr/global/security/SecurityUtil.javasrc/main/java/com/mr/global/security/jwt/JwtAccessDeniedHandler.javasrc/main/java/com/mr/global/security/jwt/JwtAuthenticationEntryPoint.javasrc/main/java/com/mr/global/security/jwt/JwtAuthenticationFilter.javasrc/main/java/com/mr/global/security/jwt/JwtTokenProvider.javasrc/main/java/com/mr/global/security/principal/CustomUserDetails.javasrc/main/java/com/mr/global/security/principal/CustomUserDetailsService.java
💤 Files with no reviewable changes (1)
- src/main/java/com/mr/global/config/SecurityConfig.java
| public AuthResponseDTO.LoginResponse socialLogin(SocialType socialType, String accessToken) { | ||
| // 1. 외부 소셜 API (카카오/구글) 통신하여 유저 프로필(email, socialId) 파싱 | ||
| // SocialUserInfo userInfo = getSocialUserInfo(socialType, accessToken); | ||
|
|
||
| // 2. TODO: User 엔티티 연동 및 가입여부 검증 (Stub 구조) | ||
| // 만약 가입 안 되어있으면 DB User 생성 -> 저장 | ||
| Long mockUserId = 1L; | ||
| String mockEmail = "user@example.com"; | ||
| String mockNickname = "뮤즈유저"; | ||
| boolean isNewUser = false; | ||
|
|
||
| String appAccessToken = jwtTokenProvider.createAccessToken(mockUserId); | ||
| String appRefreshToken = jwtTokenProvider.createRefreshToken(mockUserId); |
There was a problem hiding this comment.
🔒 Security & Privacy | 🔴 Critical | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== candidate files =="
git ls-files | rg 'AuthService\.java|CustomUserDetailsService\.java|User\.java|JwtTokenProvider\.java|UserRepository\.java|CustomUserCredentials\.java|spring-security|SecurityConfig\.java' || true
echo
echo "== AuthService excerpt =="
if [ -f src/main/java/com/mr/domain/auth/service/AuthService.java ]; then
nl -ba src/main/java/com/mr/domain/auth/service/AuthService.java | sed -n '1,220p'
fi
echo
echo "== CustomUserDetailsService excerpt =="
if [ -f src/main/java/com/mr/global/security/principal/CustomUserDetailsService.java ]; then
nl -ba src/main/java/com/mr/global/security/principal/CustomUserDetailsService.java | sed -n '1,140p'
fi
echo
echo "==Jwt token provider and user-related references =="
rg -n "createAccessToken|createRefreshToken|loadUserByUsername|findById|isActivate|ROLE|SocialType|socialId|accessToken|jwtTokenProvider" src/main/java -S || trueRepository: Musereview/BE
Length of output: 546
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== AuthService excerpt =="
sed -n '1,220p' src/main/java/com/mr/domain/auth/service/AuthService.java | cat -n
echo
echo "== CustomUserDetailsService excerpt =="
sed -n '1,140p' src/main/java/com/mr/global/security/principal/CustomUserDetailsService.java | cat -n
echo
echo "== JwtTokenProvider excerpt =="
sed -n '1,220p' src/main/java/com/mr/global/security/jwt/JwtTokenProvider.java | cat -n
echo
echo "== User entity excerpt =="
sed -n '1,220p' src/main/java/com/mr/domain/user/entity/User.java | cat -n
echo
echo "== Search for user/security/token usages =="
rg -n "createAccessToken|createRefreshToken|loadUserByUsername|findById|isActivate|ROLE|SocialType|socialId|accessToken|jwtTokenProvider|SecurityContextHolder|authentication" src/main/java -S || trueRepository: Musereview/BE
Length of output: 15775
소셜 토큰 검증과 실제 사용자 조회를 연결하세요.
socialLogin이 받은 accessToken을 검증하지 않고 userId=1L로 고정된 JWT를 발급하고, 이후 인증 주체도 실제 User/SocialAuth 조회 없이 고정된 이메일과 ROLE_USER 권한으로 반환됩니다. 이는 어떤 토큰이라도 같은 로그인 응답·권한을 얻을 수 있게 만듭니다.
CustomUserDetailsService.loadUserByUsername:userId -> UserRepository.findById와 존재하지 않을 때 예외 반환을 구현하세요. [Spring Security UserDetailsService 참고]AuthService.socialLogin: 소셜 제공자 토큰 검증 →SocialAuth조회/생성 성공 후에만 DTO의 사용자 속성과jwtTokenProvider.createAccessToken/RefreshToken(...)을 호출하세요.- JWT 클레임도 실제 사용자 ID만 담도록 일관되게 유지하세요.
📍 Affects 2 files
src/main/java/com/mr/domain/auth/service/AuthService.java#L20-L32(this comment)src/main/java/com/mr/global/security/principal/CustomUserDetailsService.java#L12-L16
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/main/java/com/mr/domain/auth/service/AuthService.java` around lines 20 -
32, Update src/main/java/com/mr/domain/auth/service/AuthService.java:20-32 in
socialLogin to validate the provider accessToken, resolve or create the
corresponding SocialAuth/User, and only then populate the response and generate
JWTs using the real user ID and attributes; remove all mock identity values.
Update
src/main/java/com/mr/global/security/principal/CustomUserDetailsService.java:12-16
in loadUserByUsername to look up the user through UserRepository.findById and
throw the appropriate authentication exception when absent, preserving real
authorities and user identity throughout JWT authentication.
There was a problem hiding this comment.
@kimyw1018 알겠습니다. 현재 PR의 인프라 구축 범위와 분리하는 방향은 괜찮습니다. 다만 실제 소셜 토큰 검증·사용자 조회 전에는 임의 토큰으로 고정 사용자 JWT가 발급될 수 있으므로, 해당 엔드포인트는 운영 노출 전 반드시 후속 PR에서 완료해 주세요.
원하시면 후속 작업을 추적할 GitHub 이슈를 생성해 드릴까요? 🐰
| AuthResponseDTO.TokenResponse tokenResponse = AuthResponseDTO.TokenResponse.builder() | ||
| .accessToken(appAccessToken) | ||
| .refreshToken(appRefreshToken) | ||
| .tokenExpirationTime(3600L) | ||
| .build(); |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
토큰 만료 시간을 JWT 설정과 동일한 소스에서 계산하세요.
JwtTokenProvider는 설정된 accessTokenValidityInMilliseconds를 사용하지만 응답은 항상 3600L을 반환합니다. 설정값이 변경되면 클라이언트가 잘못된 만료 시간을 받아 너무 일찍 또는 늦게 갱신할 수 있습니다. provider에서 실제 TTL을 노출하거나 생성된 JWT의 exp를 기준으로 응답하고, 값의 단위도 명확히 정의하세요.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/main/java/com/mr/domain/auth/service/AuthService.java` around lines 34 -
38, Update the token response construction in AuthService to derive
tokenExpirationTime from the same configured access-token validity used by
JwtTokenProvider instead of the hardcoded 3600L. Expose or reuse the provider’s
actual TTL, ensure the response unit is explicitly consistent with the API
contract, and keep the returned expiration synchronized when JWT settings
change.
There was a problem hiding this comment.
@kimyw1018 알겠습니다. 다음 PR에서 JwtTokenProvider의 실제 access-token TTL을 단일 기준으로 노출·재사용하고, 응답의 tokenExpirationTime 단위도 계약에 명시해 설정 변경 시 동기화되도록 처리하면 됩니다.
원하시면 이 작업을 추적할 GitHub 이슈를 만들어 드릴까요? 🐇
| final Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); | ||
|
|
||
| if (authentication == null || authentication.getName() == null || authentication.getName().equals("anonymousUser")) { | ||
| throw new GeneralException(CommonStatus.UNAUTHORIZED); |
There was a problem hiding this comment.
인증 정보가 없을 때 유입될 수 있는 anonymousUser 상황까지 놓치지 않고 꼼꼼하게 예외 처리해 주셨네요.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/main/java/com/mr/global/security/SecurityConfig.java`:
- Line 73: Update SecurityConfig’s configuration.setExposedHeaders call to
remove "Set-Cookie", leaving only headers that browser JavaScript can access;
keep credential handling via allowCredentials(true) unchanged.
- Around line 63-71: Update the CORS configuration in SecurityConfig so
credentialed requests use an explicit, finite production Origin allowlist
instead of the wildcard https://*.musereview.site pattern, while keeping
localhost Origins limited to development profiles. Replace allowedHeaders("*")
with only the headers required by actual requests, including Authorization and
Content-Type, and preserve the existing allowed methods.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: fd04c040-c2f7-4dac-8ff6-2175cef1fcec
📒 Files selected for processing (15)
MR_config/local/application.example.ymlsrc/main/java/com/mr/domain/auth/controller/AuthController.javasrc/main/java/com/mr/domain/auth/dto/AuthResponseDTO.javasrc/main/java/com/mr/domain/auth/entity/enums/SocialType.javasrc/main/java/com/mr/domain/auth/service/AuthService.javasrc/main/java/com/mr/domain/user/entity/enums/UserRole.javasrc/main/java/com/mr/global/security/SecurityConfig.javasrc/main/java/com/mr/global/security/SecurityUtil.javasrc/main/java/com/mr/global/security/jwt/JwtAccessDeniedHandler.javasrc/main/java/com/mr/global/security/jwt/JwtAuthenticationEntryPoint.javasrc/main/java/com/mr/global/security/jwt/JwtAuthenticationFilter.javasrc/main/java/com/mr/global/security/jwt/JwtProperties.javasrc/main/java/com/mr/global/security/jwt/JwtTokenProvider.javasrc/main/java/com/mr/global/security/principal/CustomUserDetails.javasrc/main/java/com/mr/global/security/principal/CustomUserDetailsService.java
🚧 Files skipped from review as they are similar to previous changes (4)
- src/main/java/com/mr/global/security/jwt/JwtAccessDeniedHandler.java
- src/main/java/com/mr/global/security/jwt/JwtAuthenticationEntryPoint.java
- src/main/java/com/mr/global/security/jwt/JwtAuthenticationFilter.java
- src/main/java/com/mr/domain/auth/dto/AuthResponseDTO.java
📍 개요
⛓️💥 관련 이슈
🛠️ 작업 내용
🔥 리뷰 요청 사항
✅ 체크리스트
📎 참고 사항
Summary by CodeRabbit
/api/auth/login/{socialType}에서 액세스/리프레시 토큰과 사용자 정보(신규 여부 포함) 반환*.musereview.site허용), CSRF 비활성화application.example.yml추가/보강