부트캠프/[POSCO x Codingon] 웹개발자 풀스택 과정 12기

[POSCO x Codingon] 복습 | 웹개발자 풀스택 과정 12기 10주차 회고 1

hyunh404 2024. 5. 16. 10:54
728x90

 

10주차 회고

 

 

이번 회고에서는 cross-env 설정, 세션-데이터베이스 로그인, 동적 폼 생성, 그리고 multer 모듈을 통한 파일 업로드를 중심으로 학습한 내용을 정리하고자 한다.

 

 


 

 

 

1. Cross-env 세션-데이터베이스 로그인

 

cross-env는 Node.js 환경에서 플랫폼 간 환경 변수를 설정할 수 있게 해주는 패키지로, 환경별 설정을 다르게 지정할 수 있었다.

이와 함께 세션을 활용해 로그인 정보를 데이터베이스에 저장하고 유지하는 방식도 학습했다.

 

 

세션과 데이터베이스를 연결해 로그인 정보를 효율적으로 관리할 수 있도록 하기 위해서는 세션 정보를 데이터베이스에 저장하고, 세션 ID를 이용해 사용자를 추적할 수 있다.

이를 구현하기 위해 express-session과 데이터베이스를 연동하는 방식으로 진행하였다. 특히 주로 세션 관리, 사용자 등록, 로그인, 프로필 조회, 수정, 삭제 기능을 제공하는 부분이 핵심적이었다.

 

 

Sequelize를 활용해 데이터베이스와 상호작용할 모델을 정의해주었고, config.json을 통해 데이터베이스를 연결했다.

 

config.json

 

 

다음으로 로그인을 안전하게 관리하기 위해 bcrypt 라이브러리를 사용해 비밀번호를 암호화했다.

암호화된 비밀번호와 사용자가 입력한 비밀번호를 비교하는 기능도 제공하는 유틸리티 코드를 작성해 암호화를 복습할 수 있었다.

 

 

  • bcryptPassword 함수 : 사용자가 입력한 비밀번호를 인자로 받아 bcrypt.hash 메서드를 사용해 해당 비밀번호를 암호화
  • saltRounds : 해시를 생성할 때 사용하는 솔트의 복잡도를 설정하는 값
  • 암호화된 비밀번호가 반환
  • compareFunc 함수 : 사용자가 입력한 비밀번호와 데이터베이스에 저장된 암호화된 비밀번호(dbPassword) 비교
  • bcrypt.compare : 메서드를 사용해 두 비밀번호를 비교하며 일치 여부에 따라 true 또는 false 반환

 

 

const bcrypt = require('bcrypt');
const saltRounds = 11;

// 비밀번호 암호화
const bcryptPassword = (password)=>bcrypt.hash(password, saltRounds);

// 비밀번호 비교
const compareFunc = (password, dbPassword)=>bcrypt.compare(password, dbPassword);

module.exports= {
    bcryptPassword,
    compareFunc
}

 

 


 

2. 동적 폼 복습

 

동적 폼은 사용자가 입력한 내용에 따라 실시간으로 폼 필드를 추가하거나 변경하는 기능을 구현하고 params와 map 메서드를 활용해 URL 파라미터와 배열 요소를 동적으로 처리하는 부분을 복습했다.

 

  • params는 URL에 전달된 키와 값을 처리하는 데 사용되며, 동적 라우팅을 통해 폼 데이터를 서버로 전달할 수 있었다.
  • map 메서드는 배열을 순회하며 각 요소에 대해 작업을 수행해 새로운 배열을 만드는 함수로, 동적 폼 구현에 활용할 수 있었다.
 

axios를 활용해 동적 폼 데이터를 전송하고 서버에서 받은 응답 데이터를 처리했다.

 

function clickRegister(){
            const form = document.forms['register'];
            console.log('form 입력값 확인', form.username.value);

            const hobbies = Array.from(form.hobby).filter(elem=>elem.checked === true).map(elem=>elem.value);

            console.log('hobby중 사용자가 체크한 것들', hobbies);

            const data = {
                username: form.username.value,
                gender: form.gender.value,
                birthYear: form.birthYear.value,
                birthMonth: form.birthMonth.value,
                birthDay: form.birthDay.value,
                hobby: hobbies,
            }

            axios({
                method: 'get',
                url: '/axios',
                params: data
            }).then(res=>{
                console.log(res.data);

                const {
                    username,
                    gender,
                    birthYear,
                    birthMonth,
                    birthDay,
                    hobby
                } = res.data;

                registerResult.textContent = `${username}님 환영합니다! 가입완료! 생년월일은 ${birthYear}${birthMonth}${birthDay}일! 취미는 ${hobby}`
            })
        }

 

 


 

3. Multer 모듈을 이용한 파일 업로드

 

파일 업로드 기능을 구현하기 위해 multer 모듈을 복습했다.

multipart/form-data 속성을 사용하는 폼에서 파일을 업로드할 수 있도록 설정했고

 

자동으로 폴더가 생성되지 않는 오류가 발생하기도 했지만 dest 옵션을 설정해 오류를 해결할 수 있었다.

 

 

const dest = multer({dest: 'download/'}) :

  • multer를 사용하여 기본적으로 파일을 'download/' 디렉토리에 저장하도록 설정
  • 파일 이름을 변경하지 않고 기본적으로 업로드된 파일을 저장할 때 사용

const example = multer({...}):

  • multer의 diskStorage를 사용해 파일 저장 방식 커스터마이즈

destination(req, file, cb):

  • 파일이 저장될 경로를 지정
  • 콜백 함수(cb)를 통해 'download/' 디렉토리를 지정

filename(req, file, cb):

  • 업로드된 파일의 이름 처리
  • Buffer.from(file.originalname, 'latin1').toString('utf-8'):
    • 한글 파일 이름을 지원하기 위해, 원래 파일 이름을 UTF-8로 변환
  • cb(null, file.originalname):
    • 파일 이름을 변경하지 않고 원래 이름으로 저장
const abc = multer({dest: 'uploads/'})
const uploadDetail = multer({
    storage:multer.diskStorage({
        destination(req, file, cb) {
            cb(null, 'uploads/')
        },
        filename(req,file,cb){
            file.originalname = Buffer.from(file.originalname, 'latin1').toString('utf-8')
            const ext = path.extname(file.originalname);
            cb(null, path.basename(file.originalname, ext) + Date.now() + ext)
        },
    }),
    limits: {
        fieldSize: 5*1024*1025 //5mb
    }
});

 

 

특히,

파일 업로드 폼에서 반드시 enctype="multipart/form-data" 속성을 추가해야한다는 사실은 잊지 않아야 한다.

 


 

4. 쿠키, 세션, JWT 복습

 

마지막으로 쿠키, 세션, 그리고 JWT를 복습하면서 각각의 차이점과 용도에 대해 다시 한 번 복습할 수 있었다.

  • 쿠키 : 클라이언트에 저장되는 작은 데이터로 로그인 유지에 유용하지만 보안에 취약할 수 있다.
  • 세션 : 서버에 저장되며 서버 부하가 적고 보안이 좋지만 클라이언트마다 상태를 유지해야 한다.
  • JWT : 토큰 기반 인증 방식으로 클라이언트에서 토큰을 가지고 인증을 처리하는 방법이다.

 


 

 

이번 회고를 통해 쿠키, 세션, 동적 폼 구현, 그리고 파일 업로드와 같은 중요한 개념들을 다시 한 번 복습하며 학습을 진행했다. 앞으로도 이런 기초적인 개념을 기반으로 더 복잡한 기능을 구현할 수 있도록 꾸준히 학습해야 겠다는 생각이 들었다.
728x90