Skip to content

Conversation

@kwon204
Copy link
Contributor

@kwon204 kwon204 commented Feb 17, 2025

#️⃣ 연관된 이슈>

📝 작업 내용> 이번 PR에서 작업한 내용을 간략히 설명해주세요(이미지 첨부 가능)

access token 발급 시에 만료기한도 함께 응답하도록 수정

🙏 여기는 꼭 봐주세요! > 리뷰어가 특별히 봐주었으면 하는 부분이 있다면 작성해주세요

Summary by CodeRabbit

  • New Features
    • Authentication responses now include a clear token expiration timestamp.
    • Token expiration durations are now configurable, offering improved flexibility in session management.

@kwon204 kwon204 added the 🛠️ BE Backend label Feb 17, 2025
@kwon204 kwon204 self-assigned this Feb 17, 2025
@kwon204 kwon204 requested a review from efdao as a code owner February 17, 2025 12:26
@coderabbitai
Copy link

coderabbitai bot commented Feb 17, 2025

Walkthrough

The changes update token expiration handling in the authentication flow. In the AuthService, a new configuration-injected expired variable is used to calculate an expiration timestamp (expiredAt), which is now returned in the OAuthResponse record. Likewise, the JwtProvider now obtains its token validity duration from the application properties rather than a hardcoded value. Test classes have been adjusted to set these fields via ReflectionTestUtils and include assertions to verify the expiration timestamp. A new JWT expiration configuration parameter has also been added.

Changes

File(s) Change Summary
backend/src/main/java/endolphin/backend/domain/auth/AuthService.java
backend/src/main/java/endolphin/backend/domain/auth/dto/OAuthResponse.java
Added a configuration-based token expiration mechanism: Introduced new expired variable and computed expiredAt in AuthService; updated OAuthResponse to include expiredAt.
backend/src/main/java/endolphin/backend/global/security/JwtProvider.java Replaced a hardcoded token validity duration with a configurable value injected via @Value("${jwt.expired}").
backend/src/test/java/endolphin/backend/domain/auth/AuthServiceTest.java
backend/src/test/java/endolphin/backend/global/security/JwtProviderTest.java
Updated tests to set expiration fields using ReflectionTestUtils, adjusted service mock dependencies, and added assertions for validating the token's expiration timestamp.
backend/src/test/resources/application.yml Introduced a new configuration parameter expired: 1000 in the JWT settings.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant AuthService
    Client->>AuthService: login(credentials)
    activate AuthService
    AuthService-->>AuthService: Load 'expired' duration from configuration
    AuthService->>AuthService: Calculate expiredAt = now() + expired
    AuthService-->>Client: Return OAuthResponse(token, expiredAt)
    deactivate AuthService
Loading
sequenceDiagram
    participant AppConfig
    participant JwtProvider
    AppConfig->>JwtProvider: Inject property ${jwt.expired}
    JwtProvider-->>JwtProvider: Set validityInMs accordingly
Loading

Possibly related PRs

Suggested reviewers

  • efdao

Poem

I hopped through code with whiskers bright,
Adding token time to set things right.
Expirations calculated with a spring in my step,
Configurations updated—leap and prep!
Hoppy changes in every byte,
Coding magic by day and night.
🐰✨

✨ Finishing Touches
  • 📝 Generate Docstrings (Beta)

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🔭 Outside diff range comments (1)
backend/src/test/java/endolphin/backend/global/security/JwtProviderTest.java (1)

23-43: 🛠️ Refactor suggestion

Add test coverage for token expiration.

While the basic token validation is tested, there's no test verifying that tokens actually expire after the configured validityInMs period (10 seconds).

Consider adding a test like this:

@DisplayName("토큰 만료 테스트")
@Test
void tokenShouldExpireAfterValidity() throws InterruptedException {
    // given
    Long userId = 123L;
    String email = "[email protected]";
    String token = jwtProvider.createToken(userId, email);

    // when
    Thread.sleep(11000); // Wait for token to expire (10 seconds + 1 second buffer)

    // then
    assertThatThrownBy(() -> jwtProvider.validateToken(token))
        .isInstanceOf(RuntimeException.class)
        .hasMessageContaining("expired JWT token");
}
🧹 Nitpick comments (3)
backend/src/main/java/endolphin/backend/domain/auth/AuthService.java (1)

30-31: Consider documenting the time unit in the property name.

The property name jwt.expired could be more explicit about the time unit being milliseconds.

Consider renaming to jwt.expired.millis or adding a comment in the configuration file.

backend/src/test/java/endolphin/backend/domain/auth/AuthServiceTest.java (1)

45-48: Consider using a constant for the test expiration time.

The hardcoded value 10000 could be moved to a constant or loaded from test configuration to maintain consistency.

+    private static final long TEST_TOKEN_EXPIRATION_MS = 10000;
+
     @BeforeEach
     public void setUp() {
-        ReflectionTestUtils.setField(authService, "expired", 10000);
+        ReflectionTestUtils.setField(authService, "expired", TEST_TOKEN_EXPIRATION_MS);
     }
backend/src/test/resources/application.yml (1)

47-50: JWT Expiration Parameter Configuration

A new configuration key expired: 1000 has been added under the jwt section. Please confirm that:

  • Units: The value is intended to be in milliseconds.
  • Appropriateness: The value 1000 (i.e., 1 second) matches your test and/or production scenarios. In test environments, this might be acceptable; however, ensure it aligns with the application's overall token validity expectations.

Optionally, for improved clarity, consider renaming the parameter to something like expirationMillis to immediately convey its unit.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7264c0c and 63230bd.

📒 Files selected for processing (6)
  • backend/src/main/java/endolphin/backend/domain/auth/AuthService.java (3 hunks)
  • backend/src/main/java/endolphin/backend/domain/auth/dto/OAuthResponse.java (1 hunks)
  • backend/src/main/java/endolphin/backend/global/security/JwtProvider.java (1 hunks)
  • backend/src/test/java/endolphin/backend/domain/auth/AuthServiceTest.java (3 hunks)
  • backend/src/test/java/endolphin/backend/global/security/JwtProviderTest.java (2 hunks)
  • backend/src/test/resources/application.yml (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Send PR Notification to Reviewers
🔇 Additional comments (5)
backend/src/test/java/endolphin/backend/global/security/JwtProviderTest.java (2)

8-8: LGTM on ReflectionTestUtils usage!

The test setup correctly initializes the validityInMs field using ReflectionTestUtils.

Also applies to: 20-20


20-20:

Details

❓ Verification inconclusive

Verify token validity duration in production configuration.

The test uses a 10-second validity period, which is suitable for testing but would be too short for production use.

Let's check the production configuration:


🏁 Script executed:

#!/bin/bash
# Search for JWT validity configuration in application properties/yaml files
echo "Searching for JWT validity configuration..."
fd -e yml -e yaml -e properties | xargs rg -i "validity|jwt|token.*expir"

Length of output: 220


Ensure production JWT token validity is correctly configured.
The test sets the token validity to 10 seconds (10000 ms), which is appropriate only for testing. However, the shell script output only found configuration in the test resources (backend/src/test/resources/application.yml) and did not reveal any corresponding setting in the production configuration (typically in backend/src/main/resources/application.yml). Please verify that a proper, production-appropriate JWT token validity duration is defined in your production configuration. If it’s missing or incorrect, update the configuration to reflect a safe and usable duration for production.

backend/src/main/java/endolphin/backend/domain/auth/dto/OAuthResponse.java (1)

3-8: LGTM! Clean implementation of the expiration time field.

The addition of the expiredAt field to the OAuthResponse record is well-structured and immutable, which is ideal for DTOs.

backend/src/main/java/endolphin/backend/global/security/JwtProvider.java (1)

14-15:

Details

❓ Verification inconclusive

LGTM! Good practice to make token expiration configurable.

Moving from hardcoded value to configuration improves flexibility. However, let's verify the property is properly set.


🏁 Script executed:

#!/bin/bash
# Check if jwt.expired is defined in application properties/yaml files
find . -type f -name "application*.yml" -o -name "application*.properties" | while read -r file; do
  echo "Checking $file:"
  if [[ "$file" == *.yml ]] || [[ "$file" == *.yaml ]]; then
    grep -A 1 "jwt:" "$file"
  else
    grep "jwt.expired" "$file"
  fi
done

Length of output: 691


Verify production configuration for 'jwt.expired' property

LGTM on moving token expiration to a configurable value—the use of @value is a good improvement over hardcoding. However, note that while your test configuration (./backend/src/test/resources/application.yml) defines some jwt settings (e.g., jwt.secret), the main configuration file (./backend/src/main/resources/application.yml) does not show any reference to jwt.expired. Please manually verify that your production configuration properly defines the jwt.expired property so that the injection in JwtProvider.java will work as expected.

backend/src/test/java/endolphin/backend/domain/auth/AuthServiceTest.java (1)

82-84: LGTM! Good test coverage for expiration time.

The assertions properly verify both the presence and validity of the expiration time.

Comment on lines 49 to +52
String accessToken = jwtProvider.createToken(user.getId(), user.getEmail());
return new OAuthResponse(accessToken);
LocalDateTime expiredAt = LocalDateTime.now().plus(expired, ChronoUnit.MILLIS);

return new OAuthResponse(accessToken, expiredAt);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Consider timezone implications and error handling.

A few considerations:

  1. The expiration time is created using the system's default timezone. Consider if this needs to be explicitly UTC.
  2. The JWT creation could throw exceptions that should be handled.

🏁 Script executed:

#!/bin/bash
# Check for timezone handling in the codebase
rg -l "ZoneId|ZoneOffset|TimeZone" .

Length of output: 560


Timezone and Error Handling Adjustments in AuthService

  • The expiration timestamp is currently determined by LocalDateTime.now().plus(expired, ChronoUnit.MILLIS), which relies on the system default timezone. Please assess whether explicitly using UTC (e.g., LocalDateTime.now(ZoneOffset.UTC)) could provide greater consistency—especially given that other modules (like CalendarService and CandidateEventService) appear to manage timezones more explicitly.
  • The call to jwtProvider.createToken(user.getId(), user.getEmail()) lacks any exception handling. Consider wrapping this call in a try-catch block to manage potential runtime exceptions more robustly.

Copy link
Collaborator

@efdao efdao left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

고생하셨습니다

@kwon204 kwon204 merged commit 0a40bbf into dev Feb 18, 2025
6 checks passed
@kwon204 kwon204 deleted the bugfix/be/login branch February 18, 2025 01:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🛠️ BE Backend

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants