dev/node.js

node.js 웹사이트 개발 - 회원가입, 로그인,로그아웃 구현

코딩for 2020. 10. 28. 17:08
반응형

이전글 쿠키 및 세션  [dev/node.js] - node.js 맨땅 개발하기 - 쿠키와 세션(cookie, session)

 

node.js의 데이터 베이스와 쿠키의 기본적인 사용법을 이용하여 회원가입, 로그인, 로그아웃을 구현합니다.

 

1. login-router.js

회원가입, 로그인, 로그아웃 관련 라우터 모듈

// login-router.js

const path = require("path");
var  express = require("express");
var router = express.Router();

var  controller_main = require("../controllers/login-controller");

// 로그인 라우터
router.get("/login", function(req,res){
     res.sendFile(path.join(__dirname , "../public/login.html"));
});

router.post("/login", async function(req,res){
    // 로그인 확인을 위해 컨트롤러 호출
     var result = await controller_main.SignIn(req,res);   
     res.send(result);
});

// 로그아웃
router.get("/logout", function(req,res){
     console.log("clear cookie");
     // 로그아웃 쿠키 삭제
     res.clearCookie('userid');
     res.clearCookie('username');

	 // 세션정보 삭제
	 console.log("destroy session");
     req.session.destroy();
     
     res.sendFile(path.join(__dirname , "../public/login.html"));
});

// 회원가입
router.get("/signup", function(req,res){
     res.sendFile(path.join(__dirname , "../public/signup.html"));
});

router.post("/signup", async function(req,res){
    // 회원가입 컨트롤러 호출
     var result = await controller_main.SignUp(req,res);
     res.send(result);
});


module.exports = router;

 

1. Login-Controller.js 

라우터에서 전달받은 데이터를 처리하여 처리 결과를 라우터로 응답하는 역할을 한다.

// login-controller.js

var  service_main = require("../services/login-service");

// 회원로그인 컨트롤러
exports.SignIn =  async function(req,res){
     //console.log( req.body);
     var result =  await service_main.SignIn(req);     
     if(result.code ==0)
     {
     	// 로그인 성공시 쿠키 생성
          res.cookie('userid', result.data.userid);
          res.cookie('username', result.data.name, {
               maxAge:60*60*1000,
               path:"/"
          });
          
          //  로그인 후 사용자 정보를 세션에 저장
          // req.session.user = result;
     }

     return result;
};

// 회원가입 컨트롤러
exports.SignUp =  async function(req,res){
     //console.log( req.body);

     var result =  await service_main.SignUp(req);     

     var msg = "가입완료";
     if(result ==100)
     {
          msg = "이미 존재하는 ID 입니다.";
     }
     
     var json = {code:result, msg:msg};
     console.log(json);

     return json;
};

 

3. login-service.js

컨트롤러에서 데이터를 전달받아 DB 처리등을 담당하여 처리 후 컨트롤러로 응답한다.

// login-service.js

var mariadb = require('mariadb');
var bkfd2Password = require('pbkdf2-password');
var hasher = bkfd2Password();

const pool = mariadb.createPool({
  host: '127.0.0.1', 
  port: 3308,
  user: 'root', 
  password: 'xxxx',
  connectionLimit: 5,
  database:"testDB"
});


// 로그인 서비스
exports.SignIn = async function(req){
     var json = {};
     json.code = 0;
     var conn = await pool.getConnection();    
     var userid = req.body.userid;
     var password = req.body.password;

     var query = "SELECT userid, password, salt, name FROM member where userid='" + userid +"' ;";

     var rows = await conn.query(query); // 쿼리 실행
     if(rows[0])
     {
           //저장된 password 와  hash password 가 같은지를 체크하여 로그은 성공, 실패 처리
          var userSalt = rows[0].salt;
          var userPass = rows[0].password;
          
          return  new Promise((resolve, reject) =>{
               hasher({password:password, salt:userSalt}, (err, pass, salt, hash) => {

                    if(hash != userPass)
                    {
                         json.code = 100;
                         json.msg = "패스워드 일치하지 않습니다.(운영환경 : ID 및 비밀번호가 일치하지 않습니다)";
                         json.data = {};
                    }
                    else
                    {
                         json.data = rows[0];
                    }         
                    resolve(json);
               });
          });
     }
     else
     {
          json.code = 100;
          json.msg = "ID 일치하지 않습니다.";
          json.data = {};
          return json;
     }
     
};



// 회원가입
exports.SignUp = async function(req,res){
     var resultcode = 0;

     var conn = await pool.getConnection();    
     var userid = req.body.userid;
     var password = req.body.password;
     var name = req.body.name;


     var query = "SELECT userid, password, name, salt FROM member where userid='" + userid +"';";
     var rows = await conn.query(query); // 쿼리 실행

     if(rows[0] == undefined)
     {
          hasher({password:password}, async (err, pass, salt, hash) => {

               var query = " insert into member (userid, password, name, salt, date) values ('" + userid +"','" + hash +"','" + name +"', '"+ salt +"', CURRENT_TIMESTAMP());";
               var rows = await conn.query(query); // 쿼리 실행
             });
     }
     else
     {
          // 이미 있음
          resultcode = 100;
     }



     return resultcode;
};

*  회원가입 및 로그인시 비밀번호 암호화를 위하여 npm 모듈인 "pbkdf2-password" 를 이용한다.

pbkdf2 참고 : https://www.npmjs.com/package/pbkdf2-password

 

 

* 회원가입시 전달받은 password 를 pbkdf2  모듈을 이용하여 hash 값과 salt 값을 저장을 하고

로그인시 입력한 password 를 저장된 salt 값으로 hash 값으로 만든 후 저장된 hash 와 비교하여 로그인 유무를 확인한다.

 

 

 

4. Signup.html

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script type="text/javascript">
     function signup(){
          var param = {};
          param.userid = $("#userid").val();
          param.password = $("#password").val();
          param.name = $("#name").val();
          var ajax = $.ajax({
                    url: "/signup",
                    data: param,
                    type: 'POST',
                    dataType: "JSON",
                    success: function (result) {
                         alert(result.msg);
                         location.href = "/login";
                    }
               });
     }
</script>

<div style="width:420px;">
     <div id="login" style="text-align:right;"><a href="/login">로그인 하기</div>
     <hr>
     <div  id="loginout" style="display:none;">  
          <span id="loginid"></span> <a href="/logout">로그아웃</a>
     </div>
     <div>
          <div>
               <div >아이디  : <input type="text" id="userid" name="userid" style="width:50%;"> </div>
               <div>패스워드  : <input type="password" id="password"  name="password" style="width:50%;"> </div>
               <div>이름 : <input type="text" id="name"  name="name" style="width:50%;"> </div>
          </div>
          <div></div>
     </div>
     <div  style="margin-top:8px;text-align:right;"> <input type="button" value="회원가입" onclick="signup();" /></div>
</div>

회원가입하기 

 

 

4. Login.html

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script type="text/javascript">
     function login() {
          var ajax = $.ajax({
                    url: "/login",
                    data: "userid=" + $("#userid").val() +"&password=" + $("#password").val(),
                    type: 'POST',
                    success: function (result) {
                         if(result.code == 0) {
                              $("#login").hide();
                              $("#loginout").show();
                              $("#loginName").html(result.data.name);
                         }
                         else {
                              alert(result.msg);
                         }
                    }
               });
     }
</script>
<div style="width:420px;">
     <div id="login" style="text-align:right;">로그인 </div>
     <div  id="loginout" style="display:none;">  
          <span id="loginName"></span>님 <a href="/logout">로그아웃</a>
     </div>
     <hr>
     <div>
          <div>
               <div>아이디   <input type="text" id="userid" name="userid" style="width:100%;"> </div>
               <div>패스워드   <input type="password" id="password" name="password" style="width:100%;"> </div>
          </div>
          <div></div>
     </div>
     <div  style="margin-top:8px;text-align:right;"> <input type="button" class="btnLogin" value="로그인" onclick="login();" ></div>
     <hr>
     <div style="text-align:center;"><a href="/signup" >회원가입</a></div>
</div>

로그인 하기

로그인이 성공하면 로그인쿠키 생성

 

 

 

 

반응형