Skip to content

Commit

Permalink
Merge pull request #140 from pagers-org/carpe/improve-register-logic
Browse files Browse the repository at this point in the history
feat(app): 회원 가입 완료시 JWT 토큰을 쿠키로 저장하고 인증이 필요한 요청에 Bearer 헤더를 설정하도록 합니다.
  • Loading branch information
innocarpe authored Sep 21, 2023
2 parents 57db0d6 + ddffb4b commit 1aee99d
Show file tree
Hide file tree
Showing 9 changed files with 68 additions and 10 deletions.
20 changes: 20 additions & 0 deletions .pnp.cjs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file not shown.
Binary file not shown.
2 changes: 2 additions & 0 deletions apps/react-world/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@
"@tanstack/react-query-devtools": "^4.35.3",
"@types/axios": "^0.14.0",
"axios": "^1.5.0",
"js-cookie": "^3.0.5",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.15.0",
"zustand": "^4.4.1"
},
"devDependencies": {
"@types/js-cookie": "^3",
"@types/react": "^18.2.15",
"@types/react-dom": "^18.2.7",
"@typescript-eslint/eslint-plugin": "^6.4.1",
Expand Down
19 changes: 13 additions & 6 deletions apps/react-world/src/apis/apiInstances.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { AxiosRequestConfig } from 'axios';
import axios from 'axios';
import Cookies from 'js-cookie';

// TODO: 향후 .env 파일로 분리
const BASE_URL = 'https://api.realworld.io/api';
Expand All @@ -12,14 +13,20 @@ const axiosApi = (url: string, options?: AxiosRequestConfig) => {

// POST, DELETE 등 요청 시 인증이 필요한 경우
const axiosAuthApi = (url: string, options?: AxiosRequestConfig) => {
const jwtToken = '토큰 값'; // TODO: 향후 개발
const instance = axios.create({
baseURL: url,
headers: { Authorization: 'Bearer ' + jwtToken },
...options,
});
const instance = axios.create({ baseURL: url, ...options });
return instance;
};

export const api = axiosApi(BASE_URL);
export const authApi = axiosAuthApi(BASE_URL);

// 요청 전 JWT 쿠키 유무를 확인 후 Bearer 헤더 설정
authApi.interceptors.request.use(config => {
const jwtToken = Cookies.get('jwtToken');

if (jwtToken) {
config.headers.Authorization = 'Bearer ' + jwtToken; // 토큰이 있을 때 헤더에 추가
}

return config;
});
2 changes: 2 additions & 0 deletions apps/react-world/src/apis/register/RegisterService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ class RegisterService {
return response.data;
} catch (error) {
if (isAxiosError(error) && error.response) {
console.error('Axios error occurred:', error.response.data);
throw error.response.data;
}
console.error('An unexpected error occurred:', error);
throw error;
}
}
Expand Down
11 changes: 7 additions & 4 deletions apps/react-world/src/hooks/useRegister.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type {
RegisterUserResponse,
} from '../apis/register/RegisterService.types';
import RegisterService from '../apis/register/RegisterService';
import { saveTokenToCookie } from '@utils/jwtUtils';

const useRegister = () => {
const [userData, setUserData] = useState<RegisterUserParams>({
Expand All @@ -31,14 +32,14 @@ const useRegister = () => {
const response = await RegisterService.registerUser(userData);
console.log('response: ' + JSON.stringify(response, null, 2));

// TODO: 임시로 로컬 스토리지에 토큰 저장
localStorage.setItem('jwtToken', response.user.token);
// JWT 토큰을 쿠키에 저장
if (response && response.user && response.user.token) {
saveTokenToCookie(response.user.token);
}

setIsLoading(false);
return response;
} catch (error) {
setIsLoading(false);

// TODO: 로그 제거
console.log('error: ' + JSON.stringify(error, null, 2));
if (error && typeof error === 'object' && 'errors' in error) {
Expand All @@ -47,6 +48,8 @@ const useRegister = () => {
console.error('An unexpected error occurred:', error);
}
return null;
} finally {
setIsLoading(false);
}
};

Expand Down
8 changes: 8 additions & 0 deletions apps/react-world/src/utils/jwtUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import Cookies from 'js-cookie';

export const saveTokenToCookie = (token: string) => {
Cookies.set('jwtToken', token, {
secure: true, // HTTPS에서만 쿠키 전송
sameSite: 'lax', // CSRF 공격 방지를 위한 설정
});
};
16 changes: 16 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -817,6 +817,7 @@ __metadata:
"@tanstack/react-query": ^4.35.3
"@tanstack/react-query-devtools": ^4.35.3
"@types/axios": ^0.14.0
"@types/js-cookie": ^3
"@types/react": ^18.2.15
"@types/react-dom": ^18.2.7
"@typescript-eslint/eslint-plugin": ^6.4.1
Expand All @@ -826,6 +827,7 @@ __metadata:
eslint-plugin-prettier: ^5.0.0
eslint-plugin-react: ^7.33.2
eslint-plugin-react-hooks: ^4.6.0
js-cookie: ^3.0.5
react: ^18.2.0
react-dom: ^18.2.0
react-router-dom: ^6.15.0
Expand Down Expand Up @@ -916,6 +918,13 @@ __metadata:
languageName: node
linkType: hard

"@types/js-cookie@npm:^3":
version: 3.0.4
resolution: "@types/js-cookie@npm:3.0.4"
checksum: 46ac93974776a256f3cedadf60b45ded4d905a5e69986882d8c17baa351cb2e81a691864a1f19c3ca90eaa2cb3eeb7cb5426416b487a7d54cf5ff278d39d7870
languageName: node
linkType: hard

"@types/json-schema@npm:^7.0.12":
version: 7.0.12
resolution: "@types/json-schema@npm:7.0.12"
Expand Down Expand Up @@ -3107,6 +3116,13 @@ __metadata:
languageName: node
linkType: hard

"js-cookie@npm:^3.0.5":
version: 3.0.5
resolution: "js-cookie@npm:3.0.5"
checksum: 2dbd2809c6180fbcf060c6957cb82dbb47edae0ead6bd71cbeedf448aa6b6923115003b995f7d3e3077bfe2cb76295ea6b584eb7196cca8ba0a09f389f64967a
languageName: node
linkType: hard

"js-tokens@npm:^3.0.0 || ^4.0.0, js-tokens@npm:^4.0.0":
version: 4.0.0
resolution: "js-tokens@npm:4.0.0"
Expand Down

0 comments on commit 1aee99d

Please sign in to comment.