Mini

24.9.10. 개발일지 // 인증미들웨어, 트랙잭션, 암호화 본문

CS/DB

24.9.10. 개발일지 // 인증미들웨어, 트랙잭션, 암호화

Mini_96 2024. 9. 11. 01:53

* 인증 미들웨어

  • 목표 : 로그인전에 req에 id, pw가 있는지 확인하고싶다.
  • login 전 미들웨어로 checkBody를 적어주면 된다.
this.router
    .route('/')
    .get(this.loginHome) //홈화면(로그인하기, 회원가입하기)
    .post(this.checkBody,this.login); //로그인전에 req에 id, pw 있는지 확인!
checkBody= async(req, res, next) => {
    if(!req.body.loginId || !req.body.password){
        return res.status(400).json({
            status : 'fail',
            message : 'Missing id or pw'
        });
    }
    next(); //이상이없는경우
}

비밀번호를 빼고보낸후 test

  • 모듈 각각 export 하는법
    • 객체로export 후
    • 객체로 import 하면됨
function authMiddleware(req, res, next) {
   ...
}

function checkBodyIdPw (req, res, next)  {
    ...
};

module.exports = { authMiddleware, checkBodyIdPw };
const {checkBodyIdPw} = require('../middlewares/auth');

 

 

* 비밀번호 암호화

  • create Member에서 저장할때 암호화해서 저장 // repository에서
  • login 할때 암호화해서 비교 //service 에서
npm install bcrypt
const bcrypt = require('bcrypt');
//memberRepository.js
async create(member) {
    const salt = await bcrypt.genSalt();
    const hashedPassword = await bcrypt.hash(member.pw, salt);

    const sql = `INSERT INTO ${this.tableName} (name, login_id, password) VALUES (?, ?, ?)`;
    const result = await db.query(sql, [member.name, member.loginId, hashedPassword]);
    return this.findById(result.insertId);
}
  • salt 와 함께 단방향 암호화
  • 문제 : Data too long error
  • 원인 : bcrypt는 항상 60자 고정
  • 해결 : password의 varchar를 100으로 늘림 

 

진짜 60자인지 확인
암호화 과정

//Member service.js
async login(loginId, password) {
    ...
    if(! await bcrypt.compare(password, findMember.password)){
        console.log('비밀번호가 일치하지 않습니다.');
        return null;
    }
    return findMember;
}

 

* db에 트랜잭션 적용

  • query -> commit -> release
  • query -> fail -> throw error -> release
const connection = await db.getConnection();
        await connection.beginTransaction();

        try {
            let hashedPassword = member.pw;
            if (member.pw !== undefined) {
                const salt = await bcrypt.genSalt();
                hashedPassword = await bcrypt.hash(member.pw, salt);
            }

            const sql = `UPDATE ${this.tableName} SET name = ?, login_id = ?, password = ? WHERE id = ?`;
            const result = await connection.query(sql, [member.name, member.loginId, hashedPassword, id]);

            if (result.affectedRows === 0) {
                throw new Error('업데이트할 회원을 찾을 수 없습니다.');
            }

            await connection.commit();
            return result.affectedRows;
        } catch (error) {
            await connection.rollback();
            throw error;
        } finally {
            connection.release();
        }
        // const sql = `UPDATE ${this.tableName} SET name = ?, login_id = ?, password = ? WHERE id = ?`;
        // const result = await db.query(sql, [member.name, member.loginId, member.pw, id]);
        // return result.affectedRows;

 

  • 문제 : 트랜잭션 -> 커밋전까지 실제 db 에 반영이안됨 -> find가 안되는 문제
  • 임시해결 : create 내부에서 find하는 코드가 있었는데, find부분 삭제
  • 이게 best?