-
Notifications
You must be signed in to change notification settings - Fork 0
fix: 헤더 임시 하드토큰 반영 로직 추가 #115
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -13,7 +13,33 @@ export const apiClient = axios.create({ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| withCredentials: true, // 쿠키 자동 전송 설정 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // 응답 인터셉터 (에러 처리) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // 임시 하드코딩된 토큰 (쿠키가 없을 때 사용) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const TEMP_ACCESS_TOKEN = | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOjEsImlhdCI6MTc1NDM4MjY1MiwiZXhwIjoxNzU2OTc0NjUyfQ.BSGuoMWlrzc0oKgSJXHEycxdzzY9-e7gD4xh-wSDemc'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Request 인터셉터: 쿠키가 없을 때 임시 토큰을 헤더에 추가 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| apiClient.interceptors.request.use( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| config => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // 쿠키에서 Authorization 확인 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const cookies = document.cookie.split(';'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const hasAuthCookie = cookies.some(cookie => cookie.trim().startsWith('Authorization=')); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // 쿠키가 없으면 임시 토큰을 헤더에 추가 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!hasAuthCookie) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| console.log('🔑 쿠키가 없어서 임시 토큰을 헤더에 추가합니다.'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| config.headers.Authorization = `Bearer ${TEMP_ACCESS_TOKEN}`; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| console.log('✅ Authorization 쿠키가 있어서 자동으로 전송됩니다.'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return config; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| error => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return Promise.reject(error); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+21
to
+40
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion 토큰 확인 로직을 개선하세요. 현재 구현에 다음과 같은 문제점이 있습니다:
다음과 같이 개선된 구현을 제안합니다: // Request 인터셉터: 쿠키가 없을 때 임시 토큰을 헤더에 추가
apiClient.interceptors.request.use(
config => {
- // 쿠키에서 Authorization 확인
- const cookies = document.cookie.split(';');
- const hasAuthCookie = cookies.some(cookie => cookie.trim().startsWith('Authorization='));
+ // 쿠키에서 Authorization 확인
+ const getCookie = (name: string) => {
+ const value = `; ${document.cookie}`;
+ const parts = value.split(`; ${name}=`);
+ if (parts.length === 2) return parts.pop()?.split(';').shift();
+ return null;
+ };
+
+ const authCookie = getCookie('Authorization');
- // 쿠키가 없으면 임시 토큰을 헤더에 추가
- if (!hasAuthCookie) {
- console.log('🔑 쿠키가 없어서 임시 토큰을 헤더에 추가합니다.');
- config.headers.Authorization = `Bearer ${TEMP_ACCESS_TOKEN}`;
+ // 쿠키가 없으면 임시 토큰을 헤더에 추가
+ if (!authCookie && TEMP_ACCESS_TOKEN) {
+ if (process.env.NODE_ENV === 'development') {
+ console.log('🔑 쿠키가 없어서 임시 토큰을 헤더에 추가합니다.');
+ }
+ config.headers.Authorization = `Bearer ${TEMP_ACCESS_TOKEN}`;
- } else {
- console.log('✅ Authorization 쿠키가 있어서 자동으로 전송됩니다.');
+ } else if (authCookie && process.env.NODE_ENV === 'development') {
+ console.log('✅ Authorization 쿠키가 있어서 자동으로 전송됩니다.');
}
return config;
},
error => {
return Promise.reject(error);
},
);📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Response 인터셉터: 401 에러 시 로그인 페이지로 리다이렉트 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| apiClient.interceptors.response.use( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (response: AxiosResponse) => response, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (error: AxiosError) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| import { useState, useEffect } from 'react'; | ||
|
|
||
| const TokenStatus = () => { | ||
| const [tokenStatus, setTokenStatus] = useState<string>('확인 중...'); | ||
|
|
||
| useEffect(() => { | ||
| const checkToken = () => { | ||
| const cookies = document.cookie.split(';'); | ||
| const hasAuthCookie = cookies.some(cookie => cookie.trim().startsWith('Authorization=')); | ||
|
|
||
| if (hasAuthCookie) { | ||
| setTokenStatus('✅ Authorization 쿠키 있음'); | ||
| } else { | ||
| setTokenStatus('🔑 임시 토큰 사용 중'); | ||
| } | ||
| }; | ||
|
|
||
| checkToken(); | ||
| // 5초마다 상태 확인 | ||
| const interval = setInterval(checkToken, 5000); | ||
|
|
||
| return () => clearInterval(interval); | ||
| }, []); | ||
|
|
||
| return ( | ||
| <div | ||
| style={{ | ||
| position: 'fixed', | ||
| top: '10px', | ||
| right: '10px', | ||
| background: '#333', | ||
| color: 'white', | ||
| padding: '8px 12px', | ||
| borderRadius: '4px', | ||
| fontSize: '12px', | ||
| zIndex: 9999, | ||
| fontFamily: 'monospace', | ||
| }} | ||
| > | ||
| {tokenStatus} | ||
| </div> | ||
| ); | ||
| }; | ||
|
|
||
| export default TokenStatus; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
하드코딩된 JWT 토큰을 환경변수로 이동하세요.
프로덕션 환경에서 JWT 토큰이 소스 코드에 하드코딩되어 있으면 보안 위험이 됩니다. 또한 정적 분석 도구에서도 이를 보안 위험으로 탐지하고 있습니다.
다음과 같이 환경변수로 이동하는 것을 권장합니다:
📝 Committable suggestion
🧰 Tools
🪛 Gitleaks (8.27.2)
18-18: Uncovered a JSON Web Token, which may lead to unauthorized access to web applications and sensitive user data.
(jwt)
17-18: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
🤖 Prompt for AI Agents