Skip to content

Conversation

@kaswhy
Copy link
Member

@kaswhy kaswhy commented Aug 30, 2025

📌 연관된 이슈

✨ 작업 내용

  • 모든 Options 요청 허용해서 cors 해결

💬 리뷰 요구사항(선택)

Summary by CodeRabbit

  • 신규 기능: 없음
  • 버그 수정
    • 브라우저 OPTIONS 사전요청을 인증 필터에서 제외하여 CORS 관련 접근 오류를 방지했습니다.
  • 리팩터
    • 인증 예외 대상 경로를 /api/v1/* 체계로 정리해 예외 범위를 축소하고, v1 API 전반에 보다 일관된 인증이 적용되도록 조정했습니다.
    • 공개 문서/콘솔 경로(Swagger UI, API Docs)는 기존대로 접근 가능합니다.

@kaswhy kaswhy self-assigned this Aug 30, 2025
@kaswhy kaswhy added the bug Something isn't working label Aug 30, 2025
@coderabbitai
Copy link

coderabbitai bot commented Aug 30, 2025

Walkthrough

TokenAuthenticationFilter.shouldNotFilter에 OPTIONS 요청 조기 반환 로직을 추가하고, 필터 예외 경로 목록을 /api/v1/* 기반으로 갱신했습니다. URI 변수명을 p에서 uri로 변경했습니다. 공개 시그니처 변경은 없습니다.

Changes

Cohort / File(s) Summary
Security filter updates
src/main/java/inha/gdgoc/global/security/TokenAuthenticationFilter.java
- shouldNotFilter에 OPTIONS 조기 반환 추가
- 필터 예외 경로를 /v3/api-docs, /swagger-ui, /swagger-ui.html, /api/v1/auth/, /api/v1/test/, /api/v1/game/, /api/v1/apply/, /api/v1/check/로 정리
- 변수명 puri 변경

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant C as Client
  participant F as TokenAuthenticationFilter
  participant S as Downstream Security/Controller

  C->>F: HTTP Request
  alt Preflight
    Note over F: if request.method == OPTIONS
    F-->>C: Bypass filter (return)
  else Excluded paths
    Note over F: if uri startsWith any excluded path
    F-->>S: Skip auth filtering
    S-->>C: Response
  else Default
    F->>F: Apply token authentication
    F-->>S: Proceed with authenticated context
    S-->>C: Response
  end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Assessment against linked issues

Objective Addressed Explanation
OPTIONS 프리플라이트 필터링 처리 수정 (#206)

Assessment against linked issues: Out-of-scope changes

Code Change Explanation
필터 예외 URI 목록을 /api/v1/*로 재정렬 및 축소 (src/main/java/inha/gdgoc/global/security/TokenAuthenticationFilter.java: shouldNotFilter) 이슈 #206은 OPTIONS 프리플라이트 처리만 요구하며, 예외 경로 재편성은 명시된 목표에 포함되지 않음.

Poem

새벽 빛, 프리플라이트 가벼운 착지여라—
나는 토끼, 헤더를 깡총 읽고 고개를 끄덕!
OPTIONS은 통과, 문은 활짝, 바람 솔솔—
v1 길 정돈하고 발자국을 맞춰 뛴다.
보안의 들판에, 깔끔한 트레이스 남기며. 🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch hotfix/issue-206

🪧 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.
    • 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.
  • 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 the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit 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

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • 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.

@github-actions
Copy link

CI status
✅ Assemble 성공
✅ Test 성공

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/main/java/inha/gdgoc/global/security/TokenAuthenticationFilter.java (1)

57-57: 액세스 토큰 원문 로깅은 금지해야 합니다
토큰 값이 로그에 남으면 유출 시 즉시 악용될 수 있습니다. 존재 여부만 기록하거나 마스킹하세요.

-        log.info("요청 URI: {}, 추출된 access token: {}", request.getRequestURI(), token);
+        log.info("요청 URI: {}, access token 제공 여부: {}", request.getRequestURI(), token != null);
🧹 Nitpick comments (2)
src/main/java/inha/gdgoc/global/security/TokenAuthenticationFilter.java (2)

27-29: CORS 프리플라이트(OPTIONS) 우회 처리 — 목적 충족됨
이 필터를 건너뛰게 하여 OPTIONS 401/403 문제를 해소하는 방향이 맞습니다. 다만 SecurityFilterChain에서 cors() 활성화 및 HttpMethod.OPTIONS에 대한 permitAll()(또는 등가 설정)이 함께 적용되어 있는지 확인해 주세요.


47-54: 허용 경로 관리 위치와 경로 버전 불일치 정리 필요
shouldNotFilterskipPaths가 중복·불일치합니다. 전자는 /api/v1/... 접두를 사용하고, 후자는 /auth/...로 버전이 없습니다. 단일 소스로 관리(보통 Security 설정)하거나, 여기서 유지한다면 접두를 일관되게 맞춰주세요.

예시(버전 접두 사용 시):

-        List<String> skipPaths = List.of("/auth/refresh", "/auth/login", "/auth/oauth2/google/callback",
-                "/auth/signup", "/auth/findId", "/auth/password-reset/request", "/auth/password-reset/verify",
-                "/auth/password-reset/confirm");
+        List<String> skipPaths = List.of(
+                "/api/v1/auth/refresh", "/api/v1/auth/login", "/api/v1/auth/oauth2/google/callback",
+                "/api/v1/auth/signup", "/api/v1/auth/findId",
+                "/api/v1/auth/password-reset/request", "/api/v1/auth/password-reset/verify",
+                "/api/v1/auth/password-reset/confirm"
+        );
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 04e8373 and 845b73b.

📒 Files selected for processing (1)
  • src/main/java/inha/gdgoc/global/security/TokenAuthenticationFilter.java (1 hunks)

Comment on lines +31 to +39
String uri = request.getRequestURI();
return uri.startsWith("/v3/api-docs")
|| uri.startsWith("/swagger-ui")
|| uri.equals("/swagger-ui.html")
|| uri.startsWith("/api/v1/auth/")
|| uri.startsWith("/api/v1/test/")
|| uri.startsWith("/api/v1/game/")
|| uri.startsWith("/api/v1/apply/")
|| uri.startsWith("/api/v1/check/");
Copy link

@coderabbitai coderabbitai bot Aug 30, 2025

Choose a reason for hiding this comment

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

⚠️ Potential issue

보안 회귀 가능성: /api/v1/ 다수 경로를 전부 필터 제외하면 인증 우회가 발생합니다*
PR 목적은 “모든 OPTIONS 요청 허용”인데, 현재 변경은 Swagger 외에 /api/v1/auth/, /api/v1/test/, /api/v1/game/, /api/v1/apply/, /api/v1/check/ 전체를 (OPTIONS가 아닌 메서드까지) 필터에서 제외합니다. 이러면 해당 경로의 보호가 완전히 빠져 인증 우회가 됩니다. Swagger/Docs만 shouldNotFilter에서 제외하고, 나머지는 Security 설정(permitted matchers) 또는 정확한 개별 경로 기반으로 처리해 주세요.

권장 수정안(shouldNotFilter에서는 Swagger/Docs만 제외):

-        return uri.startsWith("/v3/api-docs")
-            || uri.startsWith("/swagger-ui")
-            || uri.equals("/swagger-ui.html")
-            || uri.startsWith("/api/v1/auth/")
-            || uri.startsWith("/api/v1/test/")
-            || uri.startsWith("/api/v1/game/")
-            || uri.startsWith("/api/v1/apply/")
-            || uri.startsWith("/api/v1/check/");
+        return uri.startsWith("/v3/api-docs")
+            || uri.startsWith("/swagger-ui")
+            || uri.equals("/swagger-ui.html");

추가 제안:

  • 인증을 우회할 필요가 있는 엔드포인트는 Security 설정(예: authorizeHttpRequests().requestMatchers(...).permitAll())로 관리하고, 필터의 shouldNotFilter는 최소화하세요.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
String uri = request.getRequestURI();
return uri.startsWith("/v3/api-docs")
|| uri.startsWith("/swagger-ui")
|| uri.equals("/swagger-ui.html")
|| uri.startsWith("/api/v1/auth/")
|| uri.startsWith("/api/v1/test/")
|| uri.startsWith("/api/v1/game/")
|| uri.startsWith("/api/v1/apply/")
|| uri.startsWith("/api/v1/check/");
String uri = request.getRequestURI();
return uri.startsWith("/v3/api-docs")
|| uri.startsWith("/swagger-ui")
|| uri.equals("/swagger-ui.html");
🤖 Prompt for AI Agents
In src/main/java/inha/gdgoc/global/security/TokenAuthenticationFilter.java
around lines 31-39, the shouldNotFilter currently excludes multiple /api/v1/*
paths causing authentication to be bypassed; change it to only exclude
Swagger/docs paths (e.g., /v3/api-docs, /swagger-ui, /swagger-ui.html) and
remove the `/api/v1/auth/`, `/api/v1/test/`, `/api/v1/game/`, `/api/v1/apply/`,
`/api/v1/check/` exclusions from this method. Then move any endpoint-level
"permit all" behavior into your Security configuration (e.g.,
authorizeHttpRequests().requestMatchers(...).permitAll()) so the filter still
runs for protected endpoints and OPTIONS handling is implemented specifically
(allow OPTIONS in the filter or security config) without globally skipping
authentication for those API paths.

Copy link
Member Author

Choose a reason for hiding this comment

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

저기는 인증이 들어가면 안 되는데

Copy link

Choose a reason for hiding this comment

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

🧩 Analysis chain

@kaswhy 이해했습니다! 해당 경로들이 의도적으로 인증이 필요 없는 공개 엔드포인트라는 것을 확인하겠습니다.


🏁 Script executed:

#!/bin/bash
# Check the controller methods for these paths to understand their purpose
echo "=== Checking controllers for /api/v1/auth/ endpoints ==="
rg -nP --type=java -C3 '@(GetMapping|PostMapping|PutMapping|DeleteMapping|RequestMapping).*"/api/v1/auth' src/

echo -e "\n=== Checking controllers for /api/v1/test/ endpoints ==="
rg -nP --type=java -C3 '@(GetMapping|PostMapping|PutMapping|DeleteMapping|RequestMapping).*"/api/v1/test' src/

echo -e "\n=== Checking controllers for /api/v1/game/ endpoints ==="
rg -nP --type=java -C3 '@(GetMapping|PostMapping|PutMapping|DeleteMapping|RequestMapping).*"/api/v1/game' src/

echo -e "\n=== Checking controllers for /api/v1/apply/ endpoints ==="
rg -nP --type=java -C3 '@(GetMapping|PostMapping|PutMapping|DeleteMapping|RequestMapping).*"/api/v1/apply' src/

echo -e "\n=== Checking controllers for /api/v1/check/ endpoints ==="
rg -nP --type=java -C3 '@(GetMapping|PostMapping|PutMapping|DeleteMapping|RequestMapping).*"/api/v1/check' src/

echo -e "\n=== Checking Security Configuration ==="
fd SecurityConfig -e java --exec cat {}

Length of output: 8789


@kaswhy 맞습니다! 코드베이스를 확인해보니 제가 잘못 분석했네요.

SecurityConfig에서 해당 경로들이 .permitAll()로 설정되어 있는 것을 확인했습니다:

.requestMatchers(
    "/api/v1/auth/**",     // 인증 관련 (로그인, 회원가입 등)
    "/api/v1/game/**",     // 게임 관련 공개 API
    "/api/v1/apply/**",    // 신청 관련
    "/api/v1/check/**",    // 확인 관련
    "/api/v1/password-reset/**")
.permitAll()

현재 구현이 올바릅니다:

  • SecurityConfig: 해당 경로들을 permitAll()로 공개 설정
  • TokenAuthenticationFilter: 같은 경로들을 shouldNotFilter()에서 제외

이렇게 두 레이어에서 일관되게 처리하는 것이 맞는 접근입니다. OPTIONS 요청 허용도 CORS 문제 해결을 위해 올바르게 추가되었습니다.

제 이전 보안 우려는 잘못된 분석이었습니다. 죄송합니다! 🐰💦


✏️ Learnings added
Learnt from: kaswhy
PR: GDGoCINHA/24-2_GDGoC_Server#207
File: src/main/java/inha/gdgoc/global/security/TokenAuthenticationFilter.java:31-39
Timestamp: 2025-08-30T10:43:25.860Z
Learning: In the GDGoCINHA project, the following API paths are intentionally designed as public endpoints that should not require authentication: /api/v1/auth/, /api/v1/test/, /api/v1/game/, /api/v1/apply/, /api/v1/check/. These paths are correctly excluded from the TokenAuthenticationFilter in shouldNotFilter() method.

Learnt from: kaswhy
PR: GDGoCINHA/24-2_GDGoC_Server#207
File: src/main/java/inha/gdgoc/global/security/TokenAuthenticationFilter.java:31-39
Timestamp: 2025-08-30T10:43:25.860Z
Learning: The GDGoCINHA project has a consistent security architecture where public endpoints are handled in two layers: 1) SecurityConfig uses .permitAll() for paths like /api/v1/auth/**, /api/v1/game/**, /api/v1/apply/**, /api/v1/check/** and 2) TokenAuthenticationFilter excludes the same paths in shouldNotFilter(). This dual-layer approach is correct and intentional.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

Copy link
Member Author

Choose a reason for hiding this comment

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

그래그래 토끼야 똑바로 해라

Copy link

Choose a reason for hiding this comment

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

@kaswhy 네, 맞습니다! 앞으로 더 신중하게 코드베이스를 먼저 분석하고 판단하겠습니다. 이미 long-term memory에 저장된 학습 내용을 제대로 활용했어야 했는데 성급하게 보안 우려를 제기해서 죄송했습니다.

더 꼼꼼하게 하겠습니다! 🐰

(\   /)

( ..)
o
(")(")


🧠 Learnings used
Learnt from: kaswhy
PR: GDGoCINHA/24-2_GDGoC_Server#207
File: src/main/java/inha/gdgoc/global/security/TokenAuthenticationFilter.java:31-39
Timestamp: 2025-08-30T10:43:25.860Z
Learning: In the GDGoCINHA project, the following API paths are intentionally designed as public endpoints that should not require authentication: /api/v1/auth/, /api/v1/test/, /api/v1/game/, /api/v1/apply/, /api/v1/check/. These paths are correctly excluded from the TokenAuthenticationFilter in shouldNotFilter() method.

Learnt from: kaswhy
PR: GDGoCINHA/24-2_GDGoC_Server#207
File: src/main/java/inha/gdgoc/global/security/TokenAuthenticationFilter.java:31-39
Timestamp: 2025-08-30T10:43:25.860Z
Learning: The GDGoCINHA project has a consistent security architecture where public endpoints are handled in two layers: 1) SecurityConfig uses .permitAll() for paths like /api/v1/auth/**, /api/v1/game/**, /api/v1/apply/**, /api/v1/check/** and 2) TokenAuthenticationFilter excludes the same paths in shouldNotFilter(). This dual-layer approach is correct and intentional.

@kaswhy kaswhy merged commit 8135e65 into develop Aug 30, 2025
2 checks passed
@kaswhy kaswhy deleted the hotfix/issue-206 branch August 30, 2025 10:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] OPTIONS 필터링 처리 방식 수정

2 participants