프로젝트 모듈화 과정에서 발생한 문제를 해결한방법과 보안에 대해 고민한 부분을 정리했습니다.
모듈화란?
모듈화는 소프트웨어 개발에서 중요한 단계 중 하나로, 코드를 작은 모듈로 분리하여 관리 및 유지보수를 용이하게 합니다.
1. 파일경로 문제 해결 : import file not found
문제 상황
이전에는 모두 동일한 파일에 있었는데 모듈화를 하며 다른 파일로 나눠지게 되었습니다.
project/
├── server/
│ ├── processChatGPTRequest.js
│ └── lambda/
│ └── handler.js
└── public/
└── index.html
이 상황에서 lambda
디렉토리 내의 handler.js
가 processRequest.js
모듈을 import 해와야 하는 구조라면, 정확한 상대 경로 지정이 필요합니다.
이 상황에서 main.js
파일에서 helper.js
모듈을 불러와야 한다면, 정확한 경로를 지정해야 합니다. 그렇지 않으면 서버 실행 과정에서 import file not found
오류가 발생합니다.
해결 방법
- 모듈을 불러올 때 상대 경로를 정확하게 사용해야 합니다. 현재 파일(handler.js)이 위치한 디렉토리의 상위 디렉토리를 나타내는
..
과 모듈의 경로를 조합하여 import 해야 합니다.- 즉 이 경우에는
import { processChatGPTRequest } from "../processChatGPTRequest.js"
이 됩니다.
- 즉 이 경우에는
- 파일 이름과 경로의 대소문자 및 스펠링을 정확히 확인해야 합니다.
이런 식으로 기본적인 사항이지만 놓치는 경우 (예를 들면 세미콜론이나 중괄호 누락) 가 있으니 우선적으로 살펴봐야겠습니다.
2. CORS 설정
모듈화 과정에서 로컬 서버와 Lambda 서버를 분리하여 개발 환경을 만들었습니다. 이 경우 서버로의 요청에서 CORS (Cross-Origin Resource Sharing) 정책 문제가 발생할 수 있습니다. 즉 서로 다른 출처에서의 요청이 차단되는 문제입니다.
문제 상황
브라우저에서 서버에 요청 시 CORS 오류가 발생하는 경우 다음과 같은 오류 메시지가 나타납니다.
Access to fetch at 'http://localhost:3000/chat' from origin 'http://127.0.0.1:5500' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
해결 방법
서버 측에서 CORS (Cross-Origin Resource Sharing) 정책을 설정하여 이 문제를 해결할 수 있습니다.
Express.js와 같은 백엔드 프레임워크를 사용하는 경우, CORS 미들웨어를 추가하여 요청을 허용할 출처를 지정할 수 있습니다.
import express from "express";
import cors from "cors";
const app = express();
// CORS 미들웨어를 사용하여 모든 출처로부터의 요청을 허용합니다.
app.use(cors());
// 라우트 및 앱 설정
app.listen(PORT, () => {
console.log(`서버가 포트 ${PORT}에서 실행 중입니다.`);
});
위의 코드는 모든 출처에서의 요청을 허용하도록 설정되어 있으며, 필요에 따라 출처를 구체적으로 지정할 수 있습니다.
3. 환경 변수 관리와 API URL 노출에 대한 고민
문제 상황
API URL을 아래와 같이 하드 코딩하여 사용하면 보안에 취약할 뿐만 아니라 코드를 수동으로 변경해야 하는 등 관리가 어려울 수 있습니다.
const apiUrl = "https://api.example.com";
서버 단에서는 dotenv를 이용해서 간단히 환경변수로 지정해줄 수 있었으나 프론트 단에서는 dotenv를 사용할 수 없어 오류가 발생했습니다.
해결 방법
JSON 파일에 환경 변수를 저장하고 불러오기
config.json
파일을 아래와 같이 만들고
{
"apiUrl": "<https://api.example.com>"
}
JavaScript에서 이 파일을 로드합니다.
fetch("config.json")
.then((response) => response.json())
.then((config) => {
const apiUrl = config.apiUrl;
// apiUrl을 사용하여 API 호출
});
그러나 이 경우도 보안 문제가 있습니다.
환경 변수를 사용하여 API URL 숨기기
위에서 dotenv
를 사용하여 .env
파일을 만들고 환경 변수를 로드하는 방법도 있습니다. 이 방법은 Node.js 환경에서 사용되는 것이 일반적이지만, 브라우저에서도 동작할 수 있다고 합니다.
- Webpack 또는 Browserify 사용:
.env
파일과dotenv
패키지를 사용하기 위해 빌드 도구인 Webpack 또는 Browserify를 사용해야 합니다. 이 빌드 도구는.env
파일을 번들링하고, 클라이언트 측 JavaScript에서 사용할 수 있는 형태로 컴파일합니다. - dotenv-webpack 또는 dotenv-browserify 사용: Webpack을 사용하는 경우,
dotenv-webpack
플러그인을 설치하여 환경 변수를 번들링하도록 설정할 수 있습니다. Browserify를 사용하는 경우,dotenv-browserify
패키지를 설치하여 설정할 수 있습니다.
둘 중 선택한 빌드 도구와 라이브러리를 설정을 마친 후, 클라이언트 측 JavaScript 코드에서 dotenv
를 사용하여 환경 변수를 로드할 수 있습니다.
```jsx
import dotenv from 'dotenv';
dotenv.config();
// 이제 환경 변수를 사용할 수 있습니다.
const apiKey = process.env.API_KEY;
const apiUrl = process.env.API_URL;
console.log(apiKey, apiUrl);
```
이렇게 하면 클라이언트 측 JavaScript에서도 .env
파일의 환경 변수를 사용할 수 있습니다.
그러나 이 경우에도 클라이언트 측 코드에는 API URL이 숨겨져 있지만, 런타임에 브라우저에서 볼 수 있으므로 완전한 보안을 보장하지는 않습니다.
그래서 더 보안에 좋은 방법이 무엇인지 강구한 결과, 리액트에 도달했습니다.
React로 마이그레이션하여 API URL 숨기기
React를 사용하면 .env
로 환경변수를 설정할 수 있습니다.
환경변수로 지정했을 때의 장점
개발, 스테이징 및 프로덕션 환경에서 다른 API 엔드포인트를 사용할 수 있으며 보안성을 향상시킬 수 있습니다.
그래서 어차피 React를 공부하려고 하기도 했기에 마이그레이션을 결심하게 되는 계기가 되었습니다.