Node.js | 로그인&회원가입 02

m1njae·2022년 2월 19일
1

로그인&회원가입

목록 보기
2/7
post-thumbnail

프론트를 위한 JS 만들기

html과 연결해서 동작하도록 하는 JavaScript 파일을 만들어 주는 과정이다. 폴더 구조를 최적화해놓은 상태이다.

src폴더에 js폴더를 생성한 후, home폴더를 추가해준다. 그리고 home폴더 안에 login.js라는 파일을 생성해준다. 그리고 login.jslogin.ejs를 연결해주는 작업을 거친다.

//login.ejs

    <!DOCTYPE html>
    <html lang="ko">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <script src="/js/home/login.js"></script>   // 추가된 코드 
        <title>Login-Lecture</title>
    </head>
    <body>
        <input type="text" placeholder="아이디"><br>
        <input type="text" placeholder="비밀번호"><br>
        <button>로그인</button>
    </body>
    </html>

그리고 js파일에 접근할 수 있도록 도와주는 미들웨어를 등록해주어야 한다.

// 모듈
const express = require('express');
const app = express();

const PORT = 3000;
//라우팅
const home = require("./src/routes/home");

// 앱 세팅
app.set("views", "./src/views");
app.set("view engine", "ejs");
app.use(express.static(`${__dirname}/src/public`)); // 추가된 코드

app.use("/", home); // use -> 미들 웨어를 등록해주는 메서드

module.exports = app;

로그인 기능 구현

로그인 기능은 아이디와 비밀번호를 입력하고, 로그인 버튼을 눌릴 때, 해당 아이디와 비밀번호 값이 서버로 전달되고 서버는 데이터를 받아서 로직을 처리하게 되는 것이다. 즉, html에서 전달하는 값을 자바스크립트에서 제어할 수 있어야 한다. 이때, DOM이라는 객체를 사용한다.

DOM이란, Document Object Model의 약자로서, 자바스크립트에서 html에 존재하는 값을 가져와서 제어할 수 있게 해주는 인터페이스이다.

//login.ejs

    <!DOCTYPE html>
    <html lang="ko">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <script src="/js/home/login.js" defer></script> // 수정된 코드   
        <title>Login-Lecture</title>
    </head>
    <body>
        <input id="id" type="text" placeholder="아이디"><br> // 수정된 코드
        <input id="password" type="text" placeholder="비밀번호"><br> // 수정된 코드
        <button>로그인</button>
    </body>
    </html>

스크립트에서의 로딩 방법은 두가지로 나뉜다. async방법과 defer방법이다. async방법은 비동기적으로 스크립트를 읽는 방법이고, defer방법은 명시해준 순서대로 스크립트를 읽는 방법이다. defer방법을 통해서 먼저 읽어드려야할 부분을 지정해줄 수 있는 것이다.

//login.js

"use strict";

const id = document.querySelector("#id"), 
      // #id: 태그에 id로 부여되어있는 값을 가져오라는 명령
    password = document.querySelector("#password"),
      // #password: 태그에 password로 부여되어있는 값을 가져오라는 명령
    loginButton = document.querySelector("button");

loginButton.addEventListener("click", login);

function login() {
    const request = {
        id : id.value,
        password : password.value,
    };
    console.log(request);
}

아이디와 비밀번호를 입력 후, 로그인 버튼을 클릭하게 되면, 콘솔 창에 데이터가 뜨는 것을 확인할 수 있다.

fetch

fetch를 이용해서 브라우저에 입력한 아이디와 비밀번호를 서버에 전달하는 네트워크 통신을 진행해보는 과정이다. 먼저 서버와 프론트가 해당 데이터를 어떤 경로로 주고 받을지를 정해주어야 한다.

// login.js

fetch('/login',{
  method: "POST"
  headers: {
  	"Content-Type": "application/json"
  },
  body: JSON.stringify(request)

  // object를 문자열로 바꿔주어 JSON 형태로 만들어준다
});

위와 같은 형식으로 서버가 데이터로 전달되게 되는 것이고, 이 데이터를 받기 위해서는 /login이라는 경로와 POST라는 메소드로 데이터를 받을 수 있는 API가 마련되어 있어야 한다.

로그인 API 만들기

//home.ctrl.js

"use strict";
const output = {
    hello: function (request,response){
        response.render("home/index");
    },

    login: function (request,response){
        response.render("home/login");
    },
};

const process = {
    login: function (request, response){
        console.log(request.body);
    }
}
module.exports = {
    output,
    process,
};
//index.js

"use strict";

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

const ctrl = require("./home.ctrl");

router.get('/', ctrl.output.hello); // 수정한 코드
router.get("/login", ctrl.output.login); // 수정한 코드
router.post("/login", ctrl.process.login); // 수정한 코드

module.exports = router;

get방식으로 받는 /login경로와 POST방식으로 받는 /login경로의 코드를 이해하기 쉽게 코드를 수정해주었다. home.ctrl.js파일에 login 함수에서 request에서 body로 접근을 해야하는데, body의 정보를 보기 위해서는 미들 웨어를 등록해주어야 한다.

//in app.js

app.use(express.json());
// URL을 통해 전달되는 데이터에 한글, 공백 등과 같은 문자가 포함될 경우 제대로 인식하지 않는 문제 해결
app.use(express.urlencoded({ extended : true}));

로그인 인증 기능 만들기

로그인 가능하기 위해서는 프론트에서 받은 아이디와 비밀번호의 값을 서버에서 인증하는 과정이 필요하다. 인증을 하기 위해서는 해당 데이터를 서버가 가지고 있어야 한다. 그래서 임의로 로그인이 가능한 아이디와 비밀번호를 생성해주고 코드를 전개하였다.

// in home.ctrl.js

const users = {
    id: ["minjae","rkdalswo1021", "mj991021"],
    password: ["1234","12345","123456"],
};

const process = {
    login: function (request, response){
        const id = request.body.id,
            password = request.body.password

        if (users.id.includes(id)) {
            const idx = users.id.indexOf(id);
            if (users.password[idx] === password){
                return response.json({
                    success: true,
                });
            }
        }

        return response.json({
            success: false,
            message: "아이디 또는 비밀번호가 일치하지 않습니다."
        });
    },
}

fetch를 통해서 데이터를 전달한 후, 서버에서 응답한 데이터를 받으려면 fetch 끝에 then이라는 메소드를 사용해서 데이터를 가져올 수 있다.

//in login.js

fetch('/login',{
        method: "POST",
        headers: {
            "Content-Type": "application/json"
        },
        body: JSON.stringify(request),
  
      }).then(function(response){
          return response.json()
      }).then(function(response){
          console.log(response)});

이때, response.json()의 반환 값은 Promise이다. 기본 response의 반환 값은 response 스트림인데, .json()메소드를 통해 response 스트림을 읽을 수 있다. response는 데이터가 모두 받아진 상태가 아니다..json()으로 response 스트림을 가져와 완료할 때까지 읽는다. 다 읽은 body의 텍스트를 promise 형태로 반환한다. 라고 하는데 솔직히 이해하지 못했다. 일단은 이런게 있구나라고 생각하고 나중에 공부해보아야겠다.

로그인이 가능하지 않은 데이터와 가능한 데이터를 입력하게 되면, 다음과 같이 브라우저 콘솔 창에 로그가 뜨는 것을 확인할 수 있다.

서버의 응답 데이터 처리

//in login.js
fetch('/login',{
        method: "POST",
        headers: {
            "Content-Type": "application/json"
        },
        body: JSON.stringify(request),
  
      }).then((response) => response.json())
      .then((response) => {
          if (response.success){
          	location.href = "/";
          } else {
            	alert(response.message);
          }
	  }).catch((error) =>{
            console.error(new Error("로그인 중 에러 발생"));
        });

response.success 값이 True라면 location.href를 이용해서 경로가 '/'인 페이지로 이동시켜 준다. 그렇지 않을 경우에는 response.message의 값을 경고창으로 띄워준다. 그리고 catch문을 통해 에러 처리를 해준다.
다음과 같이 잘못된 로그인 값을 입력했을 때, 경고창을 뜨는 것을 확인할 수 있다.

느낀 점

로그인 기능을 구현하는 부분에서 DOM이나 then메소드 같은 경우에는 솔직하게 이해가 되지 않았다. 그리고 폴더 구조를 최적화시켜놓았지만, 스스로 정리가 되어있지 않다보니 집중하지 않으면 내가 무엇을 해놓았는지, 무엇을 하고 있는지 모를때가 있었다. 복습을 통해서 다시 한번 곱씹어보고, 부족한 부분들은 공부해서 채워나가야겠다.

참고

[Node.js] 백엔드 맛보기
대한민국에서 1등한 개발자의 놀라운 발표 | 심사위원 전원 만점!? | Javascript와 DOM

profile
할 수 있는 것부터 차근차근, 항해자의 공부 기록공간

0개의 댓글