Skip to content

Commit

Permalink
Merge pull request #16 from hw-coconote/feat/HC-160
Browse files Browse the repository at this point in the history
[FIX] HC-160 axios 요청에 accessToken 추가기능 수정
  • Loading branch information
jiho3634 authored Oct 2, 2024
2 parents 68579d9 + 03742fb commit ef98d0d
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 76 deletions.
59 changes: 19 additions & 40 deletions src/services/axios.js
Original file line number Diff line number Diff line change
@@ -1,59 +1,38 @@
// Axios 인스턴스를 생성하여 모든 요청에 accessToken을 포함하는 설정을 추가합니다.
// services 디렉터리 안에 axios.js 파일을 생성하는 것이 일반적입니다.
// src/services/axios.js
import axios from 'axios';

// Axios 인스턴스 생성
const apiClient = axios.create({
baseURL: 'http://localhost:8080/api/v1', // 백엔드 API 주소로 변경
headers: {
'Content-Type': 'application/json',
},
});

// 요청 인터셉터
apiClient.interceptors.request.use(
// 요청 인터셉터 설정
axios.interceptors.request.use(
(config) => {
const accessToken = localStorage.getItem('accessToken');
console.log('Access Token from localStorage:', accessToken); // 디버깅 로그

// S3 URL이 아닌 경우에만 Authorization 헤더 추가
if (accessToken && !config.url.includes('amazonaws.com')) {
config.headers.Authorization = `Bearer ${accessToken}`;
console.log('Authorization Header:', config.headers.Authorization); // 디버깅 로그
}
console.log('Final Request Config:', config); // 디버깅 로그

return config;
},
(error) => {
console.error('Request error:', error); // 에러 로그
return Promise.reject(error);
}
);

// 응답 인터셉터 (토큰 만료 시 자동 갱신)
apiClient.interceptors.response.use((response) => {
// 필요 시 응답 인터셉터도 추가할 수 있음
axios.interceptors.response.use(
(response) => {
// 응답 성공 시 처리할 로직
return response;
}, async (error) => {
const originalRequest = error.config;

if (error.response.status === 401 && !originalRequest._retry) {
originalRequest._retry = true; // 무한 루프 방지
const refreshToken = localStorage.getItem('refreshToken');

if (refreshToken) {
try {
const response = await axios.post('http://localhost:8080/auth/refresh-token', {
token: refreshToken,
});

const newAccessToken = response.data.accessToken;
localStorage.setItem('accessToken', newAccessToken); // 새로운 Access Token 저장

originalRequest.headers.Authorization = `Bearer ${newAccessToken}`; // 새로운 토큰으로 요청 갱신
return apiClient(originalRequest); // 원래 요청 다시 실행
} catch (refreshError) {
console.error('토큰 갱신 실패:', refreshError);
// 여기서 추가로 로그아웃 처리 등 가능
}
}
}
},
(error) => {
// 응답 에러 처리
console.error('Response error:', error); // 에러 로그
return Promise.reject(error);
});
}
);

export default apiClient;
export default axios;
36 changes: 31 additions & 5 deletions src/views/HomePage.vue
Original file line number Diff line number Diff line change
@@ -1,17 +1,43 @@
<template>
<v-app>
<h1>test</h1>

<!-- 로그인 상태에 따라 버튼을 조건부 렌더링 -->
<v-btn v-if="!isLoggedIn" @click="login">로그인</v-btn>
<v-btn v-if="isLoggedIn" @click="logout">로그아웃</v-btn>
</v-app>
</template>

<script>
export default {
data() {
return {};
return {
isLoggedIn: false, // 로그인 상태 관리
};
},
created() {
// 페이지가 로드될 때 로그인 상태 확인
this.checkLoginStatus();
},
methods: {
// 로그인 버튼 클릭 시
login() {
// /login 페이지로 이동
this.$router.push("/login");
},
// 로그아웃 버튼 클릭 시
logout() {
// 로그아웃 처리: localStorage에서 토큰 제거
localStorage.removeItem("accessToken");
localStorage.removeItem("refreshToken");
this.isLoggedIn = false; // 로그인 상태 갱신
},
// 로그인 상태 확인
checkLoginStatus() {
const accessToken = localStorage.getItem("accessToken");
// accessToken이 있으면 로그인 상태로 설정
this.isLoggedIn = !!accessToken;
},
},
computed: {},
created() {},
methods: {},
};
</script>
55 changes: 49 additions & 6 deletions src/views/OAuth2Success.vue
Original file line number Diff line number Diff line change
@@ -1,13 +1,29 @@
<template>
<div class="success-page">
<h1>로그인 성공</h1>
<!-- 로그아웃 버튼 추가 -->

<!-- 로그아웃 버튼 -->
<button @click="logout">로그아웃</button>

<!-- 멤버 정보 확인 버튼 -->
<button @click="fetchMemberInfo">멤버 정보 확인</button>

<!-- 응답 메시지 출력 -->
<div v-if="memberInfo">
<h3>응답: {{ memberInfo }}</h3>
</div>
</div>
</template>

<script>
import axios from "axios";
export default {
data() {
return {
memberInfo: null, // API 응답 저장
};
},
mounted() {
this.handleOAuth2Success();
},
Expand Down Expand Up @@ -37,19 +53,42 @@ export default {
console.error("로컬 스토리지 저장 실패:", error);
}
},
// 로그아웃 메서드 추가
// 로그아웃 메서드
logout() {
try {
// 로컬 스토리지에서 토큰 삭제
localStorage.removeItem("accessToken");
localStorage.removeItem("refreshToken");
// 로그아웃 후 로그인 페이지로 리다이렉트
this.$router.push("/login"); // 실제 로그인 경로로 변경
this.$router.push("/login");
} catch (error) {
console.error("로그아웃 중 에러 발생:", error);
}
},
// 멤버 정보 확인 메서드
async fetchMemberInfo() {
try {
const accessToken = localStorage.getItem("accessToken");
if (!accessToken) {
console.error("액세스 토큰이 없습니다.");
return;
}
// Axios GET 요청 보내기
const response = await axios.get(
"http://localhost:8080/api/v1/member/me"
// , {
// headers: {
// Authorization: `Bearer ${accessToken}`,
// },
// }
);
// 응답 데이터를 memberInfo에 저장
this.memberInfo = response.data;
console.log("응답:", response.data);
} catch (error) {
console.error("멤버 정보 요청 중 에러 발생:", error);
}
},
},
};
</script>
Expand All @@ -67,4 +106,8 @@ button {
button:hover {
background-color: #ff0000;
}
h3 {
margin-top: 20px;
}
</style>
25 changes: 0 additions & 25 deletions src/views/YourComponent.vue

This file was deleted.

0 comments on commit ef98d0d

Please sign in to comment.