pgms

[6주차] - [9기] 타입스크립트로 함께하는 웹 풀 사이클 개발(React, Node.js) 10회차 - 28

Ejah 2026. 2. 12. 22:45
// user.js

const express = require('express');
const router = express.Router();
const conn = require('../mariadb');

const {
    join,
    login,
    passwordResetRequest,
    passwordReset  
} = require('../controller/UserController');

router.use(express.json());

router.post('/join', join);
router.post('/login',login);
router.post('/reset',passwordResetRequest);
router.put('/reset',passwordReset);

module.exports = router
// UserController

const conn = require('../mariadb');
const {StatusCodes} = require('http-status-codes');
const jwt = require('jsonwebtoken');
const crypto = require('crypto'); // crypto 모듈 : 암호화
const dotenv = require('dotenv');
dotenv.config();

const join = (req, res) => {
    const {email, password} = req.body;

    let sql = 'INSERT INTO users (email, password) VALUES (?, ?)';

    // 비밀번호 암호화된 비밀번호 DB에 저장
    const salt = crypto. randomBytes(10) .toString('base64');
    const hashPassword = crypto.pbkdf2Sync(password, salt, 10000, 10, 'sha512').toString('base64');

    // 회원가입 시 비밀번호를 암호화해서 암호화된 비밀번호와, salt 값을 같이 저장
    // 로그인 시, 이메일&비밀번호(날 것) => salt값 꺼내서 비밀번호 암호화 해보고 => 디비 비밀번호랑 비교
    
    let values = [email, hashPassword, salt];
    conn.query(sql, values,
        (err, results) => {
            if(err) {
                console.log(err);
                return res.status(StatusCodes.BAD_REQUEST).end();
            }

            return res.status(StatusCodes.BAD_REQUEST).json(results);
        })
};

const login = (req, res) => {
    const {email, password} = req.body;

    let sql ='SELECT * FROM users WHERE email = ?';
    conn.query(sql, email,
        (err, results)=> {
            if(err){
                console.log(err);
                return res.status(StatusCodes.BAD_REQUEST).end();
            }

            const loginUser = results[0];

           // salt값 꺼내서 날 것으로 들어온 비밀번호를 암호화 해보고
            const hashPassword = crypto.pbkdf2Sync(password, loginUser.salt, 10000, 10, 'sha512').toString('base64');

            // => 디비 비밀번호랑 비교
            if(loginUser && loginUser.password == hashPassword){
                //토큰 발행
                const token = jwt.sign({
                    email : loginUser.email
                }, process.env.PRIVATE_KEY,{
                    expiresIn : '5m',
                    issuer : "junhyun"
                });

                //토큰 쿠키에 담기
                res.cookie("token", token,{
                    httpOnly : true
                });
                console.log(token);

                return res.status(StatusCodes.OK).json(results);
            } else {
                return res.status(StatusCodes.UNAUTHORIZED).end();
            }            
        }
    )
};

const passwordResetRequest = (req, res) => {
    const { email } = req.body;

    let sql = 'SELECT * FROM users WHERE email = ?';

    conn.query(sql, email, (err, results) => {
        if (err) {
            console.log(err);
            return res.status(StatusCodes.BAD_REQUEST).end();
        }

        // 이메일로 유저가 있는지 찾아봅니다!
        const user = results[0];

        if (user) {
            return res.status(StatusCodes.OK).json({
            email: email
        });
        } else {
            return res.status(StatusCodes.UNAUTHORIZED).end();
        }
    });
};


const passwordReset = (req, res) => {
    const { email, password } = req.body;

    let sql = 'UPDATE users SET password=?, salt=? WHERE email=?';

    // 암호화된 비밀번호와 salt 값을 같이 DB에 저장
    const salt = crypto.randomBytes(10).toString('base64');
    const hashPassword = crypto
        .pbkdf2Sync(password, salt, 10000, 10, 'sha512')
        .toString('base64');

    let values = [password, salt, email];

    conn.query(sql, values, (err, results) => {
        if (err) {
            console.log(err);
            return res.status(StatusCodes.BAD_REQUEST).end();
        }

        if (results.affectedRows == 0)
            return res.status(StatusCodes.BAD_REQUEST).end();
        else
            return res.status(StatusCodes.OK).json(results);
        });
};




module.exports = {
    join,
    login,
    passwordResetRequest,
    passwordReset
};