☑️What I Learn
.env 파일 aka 닷
git, 오픈소스에 올리면 안되는 값 (포트, DB 접속 정보, API_KEY 등)
dotenv 패키지를 사용하며, 환경변수 파일을 외부에 만들어 저장해서 소스코드 내에서 하드코딩하지 않고 사용한다.
애플리케이션의 환경 설정 정보를 저장하는데 사용한다.
1. 환경 변수 저장
DB_HOST=localhost
DB_USER=root
DB_PASS=s1mpl3
API_KEY=12345-abcde
*환경변수 : os 에서 프로세스 생성할때 참조하는 변수. 프로세스가 컴퓨터에서 동작하는 방식에 영향을 미치는 동적인 값들의 모임
2. 보안 강화
.gitignore 파일에 추가해 정보가 외부로 노출되는 것을 막는다.
3. 환경별 설정관리
- .env.development
- .env.test
- .env.production
4. 동기화 설정 변경
모드 수정하지 않고 한번에 값을 수정한다. 수시로 바뀌는 배포 과정에서 유용하다.
5. node.js 기반 에서는 dotenv 라이브러리로 사용할 수 있다
(당연히 React에서도 dotenv를 사용한다) > Create-React-App으로 생성한다면 기본적으로 포함되어 있다.
사용법
프로젝트의 최상위 루트에 파일을 만든다. (package.json 파일과 동일한 선상)
환경변수를 .env 파일에 저장하고, process.env로 로드하는 의존성 모듈이다.
이름=값 (리액트 환경 REACT_APP_이름=값으로 앞부분은 필수!) > 띄어쓰기 X
const dotenv = require("dotenv");
dotenv.config();
app.listen(process.env.PORT);
.gitignore 파일 env 설정
# dotenv environment variable files
.env
.env.development.local
.env.test.local
.env.production.local
.env.local
*참고로 .gitignore 기본 설정값은 깃허브에서 가져왔다.
http-status-codes
HTTP 상태코드 확인하는 방법
프론트엔드에서도 사용할 수 있다고 하는데, 번들링 도구(Webpack, Parcel, Vite 등)을 사용해 번들링 해야 한다고 한다. Vite 에서 npm으로 설치하고, import하면 사용할 수 있는 듯 하다.
routes > controller
모듈화, 재사용성 등의 특징으로 프론트엔드의 `컴포넌트`와 비슷한 요소인것 같다는 느낌을 받았다.
차이점
컨트롤러 : 클라이언트의 요청을 받아 처리하고, DB와 통신하는 작업을 한다.
컴포넌트 : UI, 동작시키는 것과 조금 더 유사하다.
동작하는 위치는 다르지만, 역할과 동작 로직은 유사한 측면이 있다!
컨트롤러는 MVC 아키텍처의 연결자 역할
컴포넌트는 독립적으로 동작하는 구성요소 중 하나
공통적으로 사용자와의 상호작용을 담당하고, 해당 상호작용에 대한 적절한 처리를 한다. 예를 들어, 사용자가 요청한 작업을 수행하고, 데이터를 처리하거나 뷰를 업데이트한다. 또한 이벤트 처리, 상태 관리, 렌더링 등의 기능도 둘 다 수행할 수 있다.
Controller = Component + RequestMapping
UnAuthorized 401 vs Forbidden 403
두 요소가 많이 혼동 된다고 한다.
401 : 클라이언트가 인증되지 않았기 때문에 요청을 정상적으로 처리할 수 없다
- 로그인이 되어있지 않은 상태에서 무언가를 요청하는 경우
403 : 클라이언트가 해당 요청에 대한 권한이 없다고 알려주는 것
- 로그인 ok, 남의 정보에 접근하려고 하는 경우
- 관리자와 일반 사용자가 분리되어 있는 경우
crypto 모듈의 암호화
일방향 암호화를 사용하기 때문에, 복호화 할 방법이 중요함!
//비밀번호 암호화
const salt = crypto.randomBytes(10).toString("base64");
const hashPwd = crypto
.pbkdf2Sync(password, salt, 10000, 10, "sha512")
.toString("base64");
let values = [email, hashPwd, salt]; //암호화된 pwd와 salt 값을 같이 DB에 저장
로그인 할때
//salt 값 꺼내서 날것으로 들어온 비밀번호를 암호화 해보고
const hashPwd = crypto
.pbkdf2Sync(password, loginUser.salt, 10000, 10, "sha512")
.toString("base64");
//DB 비밀번호랑 비교
if (loginUser && loginUser.password == hashPwd) {
//...
*백엔드 암호화 기법 cs 지식
여기에서 crypto 모듈의 SHA 해시함수 알고리즘을 사용한것
이외에도 LFSR, AES, IDEA, DH, RSA 의 암호화 알고리즘을 대중적으로 많이 사용한다고 한다.
JOIN 으로 외래키 연결
`Ref: books.category_id > category.id`
DATE_ADD(), DATE_SUB()
몰랐던 sql 문..!!
특정 날짜에 일정 기간을 추가하거나 빼는데 사용한다.
EX)
현재 날짜에 3일을 더한 날짜 찾기:
SELECT DATE_ADD(CURRENT_DATE(), INTERVAL 3 DAY);
특정 날짜에 1주를 뺀 날짜 찾기:
SELECT DATE_SUB('2024-05-27', INTERVAL 1 WEEK);
현재 날짜와 시간에 1년을 더한 값 찾기:
SELECT DATE_ADD(NOW(), INTERVAL 1 YEAR);
특정 날짜에 2개월을 더한 날짜 찾기:
SELECT DATE_ADD('2024-05-27', INTERVAL 2 MONTH);
페이징
백엔드
- 프론트에서 쿼리 파라미터로 `/books?limit={page당 도서 수}¤tPage={현재 page}`
- 페이지 번호를 받는다.
- 페이지당 항목수 limit 받는다.
- OFFSET(DB에서 조회할 데이터의 시작 위치)를 계산한다. 페이지 번호와 limit 을 통해 계산
- sql문 맨 마지막에 `SELECT * FROM your_table LIMIT ${pageSize} OFFSET ${offset}` 사용한다.
app.get('/data', (req, res) => {
const page = req.query.page || 1;
const pageSize = req.query.pageSize || 10;
const offset = (page - 1) * pageSize;
const query = `SELECT * FROM your_table LIMIT ${pageSize} OFFSET ${offset}`;
connection.query(query, (error, results) => {
if (error) {
console.error('Error fetching data:', error);
res.status(500).json({ error: 'Internal server error' });
} else {
res.json(results);
}
});
});
프론트엔드
- 서버에 데이터 요청을 보낼때 페이지번호와 페이지 크기를 쿼리 파라미터로 함께 전달한다. `http://localhost:3000/data?page=${page}&pageSize=${pageSize}`
const fetchData = async (page, pageSize) => {
try {
const response = await fetch(`http://localhost:3000/data?page=${page}&pageSize=${pageSize}`);
///...
☑️Liked, Learned, Lacked, Longer for
.env 파일에 카카오 지도 api key를 사용하면서, 환경변수에 활용성에 대해 더 깊게 고민할 수 있었다. 또 하나 알아감!
그리고 이전에는 Create-React-App으로 써봤어서 자연스러웠는데 데브코스나 이번 플젝에서는 dotenv를 사용해서 자세한 부분을 알 수 있어서 좋았다. 라이브러리 세팅 직접 하기가 개발자 사이에서 유행이라고 하던데 이전에는 이해할 수 없었다;; 좋은 세팅이 있는데 왜 굳이 바꾸는가…. 이제는 이해할 수 있다!
컨트롤러와 컴포넌트는 단지 내가 이해한바 일뿐, 틀린 정보를 가지고 있을 것 같아 불안하다.. 지피티야 뻥친거 아니지?
비밀번호 암호화 기법 crypto 에서 꽤 복잡하지만 재미있었다! 역시 인증 토큰 관리 로직 어렵지만 재밌어..!! 프론트엔드에서 토큰 쓰는게, 이렇게 만들어지고 관리되는구나를 점점 정확히 이해되는 것 같다.
페이징 > 이전에 백엔드에서 전체정보를 한번에 넘겨주면, 프론트에서 인덱스를 통해서 원하는만큼 끊어서 쓰라고 해서 이러한 방법만 있는줄 알았는데, 백엔드에서 처리할 수 있는 방법이 있었다니 신기했다. 아마 알라딘 API에 해당 정보가 없어서 그런가 싶은데.. 잘 모르겠다. 지금 생각하면 될것같은데 하는 의심이 피어오른다ㅋㅋ
데브코스 과정을 통해서 백엔드에서 할 수 있는 역할, 프론트에서 할 수 있는 역할이 구분이 되고 있어서 좋다. 그런데 양쪽을 이해할수록 어디까지 할 수 있는지 혼란스러워진다… 정확히 판단할 수 있는 기량을 키우고 싶다.
✔️이번주에는 플젝 백엔드에서 API 명세서 주기로 했는데, 오류가 잦아서 같이 설계해보는 시간을 가지려고 한다. 데브코스에서 학습한 역량을 제대로 보여주겠다💪
✔️새벽공부 말고, 낮에 공부하자ㅜㅜ
✔️TIL, WIL, 개블쓰, 알고리즘 이외의 학습글 작성하기
✔️깃허브 리팩토링하기