본문으로 바로가기
로그인 로직
  1. 클라이언트가 아이디, 패스워드를 GET으로 서버에 보낸다.
  2. /auth/login으로 들어온 GET 요청의 데이터를 컨트롤러로 보낸다.
  3. 컨트롤러에서 USER의 데이터를 모델로 보낸다.
  4. 모델에서 로그인 성공유무를 컨트롤러로 콜백해준다.
  5. 컨트롤러에서 성공유무를 클라이언트로 보낸다.

 

아이디와 비밀번호 모두가 일치한다면 JWT 토큰을 발행하여 클라이언트에 전송한다.

 

소스코드

routes/user.js

const express = require('express');
const router = express.Router();
const controller = require('../controllers/usercontroller');
const {validateRegister} = require('../middleware/users');

router.post('/register',validateRegister,controller.insertUserProcess);
router.get('/login',controller.loginProcess);


module.exports = router;

controllers/usercontroller.js

const User = require('../models/usermodel');

exports.insertUserProcess = (req,res) => {
   let item={
       'id':req.body.id,
       'username':req.body.username,
       'password':req.body.password,
       'email':req.body.email
   };
   User.insertData(item,(result)=>{
       if(result){
           if(result.affectedRows===1){
               res.status(201).send({
                   message:'create ID success!'
               });
           }
           else{
            res.status(409).send({
                message:'signup failed! because duplicate error, use a different ID'
            });
           }
       }
   })
}

exports.loginProcess = (req,res) => {
    let item={
        'id':req.body.id,
        'password':req.body.password
    };
    User.checkUser(item,(result)=>{
        if(result===0){
            res.status(404).send({
                message:'No matching id, please check your id'
            });
        }
        else if(result===1){
            res.stauts(401).send({
                message:'compare server error'
            });
        }
        else if(result===2){
            User.tokenIssue(item,(token)=>{
                res.status(201).send({
                    message:'success',
                    token
                });
            });
        }
        else if(result===3){
            res.status(401).send({
                message:'password error'
            });
        }
        else{
            res.status(401).send({
                message:'Server Error'
            });
        } 
    });
}

models/usermodel.js

const bcrypt = require('bcrypt');
const db=require('../db');
const jwt=require('jsonwebtoken');
/**
 * 신규 회원가입을 요청하여 조건에 성립하면 데이터베이스에 입력한다.
 * @param {*} data : input data
 * @param {*} cb : call back
 */
exports.insertData = (data,cb) => {
    const saltRound=10;
    bcrypt.genSalt(saltRound,(err,salt)=>{
        if(err) throw new Error(err);
        bcrypt.hash(data.password,salt,(err,hash)=>{
            if(err) throw new Error(err);
            let sql = 'insert into user(id,password,email,username) values(?,?,?,?)';
            let bindParam = [
                data.id,
                hash,
                data.email,
                data.username,
            ];
            db.con.query(sql,bindParam,(err,results,fields)=>{
                if(err){
                    cb(err);
                    throw new Error(err);
                }
                else{
                    cb(JSON.parse(JSON.stringify(results)));
                }
            });
        });
    });
};

/**
 * 로그인 요청시 아이디와 패스워드를 확인한다.
 * @param {*} data : input data
 * @param {*} cb : callback ---> 
 * 0 : no match id in database
 * 1 : compare error
 * 2 : id and password correct
 * 3 : password error
 */
exports.checkUser = (data,cb) => {
    let sql = 'select id,password from user where id=?'
    let bindParam = [
        data.id
    ];
    db.con.query(sql,bindParam,(err,results,fileds)=>{
        const count=results.length;
        if(err){
            console.log("checkUser sql error");
            cb(results);
            throw new Error(err);
        }
        if(count===0){
            console.log("no find id cb err");
            cb(0);
        }
        else{
            bcrypt.compare(data.password,results[0].password,(err,res)=>{
                if(err){
                    console.log("compare err");
                    cb(1);
                    throw new Error(err);
                }
                if(res){
                    console.log("password correct");
                    cb(2);
                }
                else{
                    console.log("password wrong");
                    cb(3);
                }
            });
        }
    })
}

/**
 * 
 * @param {*} data : input data
 * @param {*} cb : token call back
 */
exports.tokenIssue = (data,cb) =>{
    const token = jwt.sign({
        id:data.id
    },'SECRETKEY',{expiresIn:"30d"});
    cb(token);
}
Comment

get 요청 - /auth/login

GET 요청 JSON 형식

{
    "id":"아이디",
    "password":"비밀번호"
}

로그인 예외케이스

  • DB에 없는 ID 요청은 오류메시지를 보낸다.
  • 아이디는 맞지만 패스워드가 틀릴경우 오류메시지를 보낸다.
  • 로그인 성공시 성공메시지와 토큰을 보낸다. 토큰은 id값과 연관되어 있다.