공대생

로그인 구현절차(참고용) 본문

한이음/웹페이지 제작

로그인 구현절차(참고용)

상수나무 2021. 12. 10. 20:56

FrontEnd

1. index.js

const userRouter = require('./src/routes/home/user'); //user.js 파일에 있는 라우터들을 가져옴
//템플릿 엔진 ejs 사용
app.set('views', __dirname + '/src/views');
app.set('view engine', 'ejs');
app.use('/user', userRouter) //userRouter 사용

2. user.js (get)

var express = require('express');
var router = express.Router();

//ctrl 받아오기
const ctrl = require("./home.ctrl");

router.get('/login', ctrl.output.login);
router.get('/register', ctrl.output.register);

router.post('/login', ctrl.process.login);
router.post('/register', ctrl.process.register);


module.exports = router;

3. home.ctrl.js (output)

"use strict"

const User = require("../../models/User")
const Detail = require("../../models/Detail")

const output = {
    login: (req, res) => {
        res.render('login'); //login.ejs를 그림
    },
    
    register: (req, res) => {
        res.render('register'); //register.ejs를 그림
    },

    detail: (req, res) => {
        res.render('detail'); //detail.ejs를 그림
    },
};



const process = {
    login: async (req, res) => {
        const user = new User(req.body); //client가 전달한 request 데이터를 넣음
        const response = await user.login(); //User에서 res 받음
        return res.json(response); //받은 res를 client한테 json형태로 전달
    },

    register: async (req, res) => {
        const user = new User(req.body); 
        const response = await user.register(); 
        return res.json(response); 
    },

    detail: async (req, res) => {
        const detail = new Detail(req.body); 
        const response = await detail.search(); 
        return res.json(response); 
    }

};

//ctrl 내보내기
module.exports = {
    output,
    process,
};

4. Login.ejs ( <= res.render('login'); //login.ejs를 그림)

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>로그인페이지</title>
    <link href="https://fonts.googleapis.com/css2?family=Jua&display=swap" rel="stylesheet">
    <style>
        * {
            font-family: 'Jua', sans-serif;
        }

        .mytitle {
            color: black;
            width: 300px;
            height: 150px;
            background-color: gold;
            background-position: center; /*텍스트정렬*/
            background-size: cover;

            border-radius: 10px;
            text-align: center;
            padding-top: 40px;
        }

        .insert {
            padding-top: 20px;
            padding-left: 65px;
        }

        .button {
            margin: 10px auto; /*화면 양쪽 여백 동등하게 맞춰짐(센터로감)*/
            width: 80px;
            height: 30px;
            font-size: 15px;
        }

        .login_style {
            width: 80px;
            height: 30px;
            font-size: 15px;
        }

        .register_style {

            width: 80px;
            height: 30px;
            font-size: 15px;
        }

        .wrap {
            margin: 10px auto; /*화면 양쪽 여백 동등하게 맞춰짐(센터로감)*/
            width: 300px;
        }
    </style>
    <link rel="stylesheet" href="/css/home/login.css">
    <script src="/js/home/login.js" defer></script>
</head>

<body>
    <div class="login-page">
        <div class="form">
          <form class="login-form">
            <input id="id" type="text" placeholder="아이디"/>
            <input id="psword" type="password" placeholder="비밀번호"/>
            <p id="button">로그인</p>
            <p class="message">Not registered? <a href="/user/register">Create an account</a></p>
          </form>
        </div>
      </div>
</body>
</html>

<!--Copyright (c) 2021 by Aigars Silkalns (https://codepen.io/colorlib/pen/rxddKy)-->

5. login.js( <= <script src="/js/home/login.js" defer></script>)

"use strict";

//html에 입력된 아이디와 비밀번호를 js에서 제어해야함
//DOM-> javascript에서 html에 존재하는 데이터들을 기져와 제어할 수 있게하는 인터페이스 
//const id = document.querySelector("선택자");
const id = document.querySelector("#id"),
    psword = document.querySelector("#psword"),
    loginBtn = document.querySelector("#button");

loginBtn.addEventListener("click", login);

function login() {
    const req = {
        id: id.value,
        psword: psword.value,
    };
    //아이디, 비밀번호 서버에 전달
    //fetch(전달할 경로, 전달할 데이터)
    fetch("/user/login", {
        method: "POST", //body로 데이터 전달할 때는 POST로 전달해야함
        headers: {
            "Content-Type": "application/json",
        },
        body: JSON.stringify(req), //req를 JSON형태로 감싸줌
    })
        .then((res) => res.json()) //req해서 서버에서 보낸 res 받기
        .then((res) => {
            if(res.success){ //로그인 성공 시 루트로 이동
                location.href = "/";
            } else { //로그인 실패 시 실패 메세지 띄움
                alert(res.msg); 
            }
        })
        //에러처리
        .catch((err) => {
            console.error(new Error("로그인 중 에러 발생"));
        });
}
POST로 사용자가 입력한 아이디, 비밀번호 body 전달

 

BackEnd

1. user.js (post)

var express = require('express');
var router = express.Router();

//ctrl 받아오기
const ctrl = require("./home.ctrl");

router.get('/login', ctrl.output.login);
router.get('/register', ctrl.output.register);

router.post('/login', ctrl.process.login);
router.post('/register', ctrl.process.register);


module.exports = router;

2. home.ctrl.js (process)

"use strict"

const User = require("../../models/User")
const Detail = require("../../models/Detail")

const output = {
    login: (req, res) => {
        res.render('login'); //login.ejs를 그림
    },
    
    register: (req, res) => {
        res.render('register'); //register.ejs를 그림
    },

    detail: (req, res) => {
        res.render('detail'); //detail.ejs를 그림
    },
};



const process = {
    login: async (req, res) => {
        const user = new User(req.body); //client가 전달한 request 데이터를 넣음
        const response = await user.login(); //User에서 res 받음
        return res.json(response); //받은 res를 client한테 json형태로 전달
    },

    register: async (req, res) => {
        const user = new User(req.body); 
        const response = await user.register(); 
        return res.json(response); 
    },

    detail: async (req, res) => {
        const detail = new Detail(req.body); 
        const response = await detail.search(); 
        return res.json(response); 
    }

};

//ctrl 내보내기
module.exports = {
    output,
    process,
};
User class로 body 넘겨줌

3. User.js

"use strict"

const UserStorage = require("./UserStorage");

class User {
    constructor(body) { //body를 받음
        this.body = body;
    }

    //await은 async함수 안에서만 동작
    async login() {
        const client = this.body;
        try {
            const { userID, userPassword } = await UserStorage.getUserInfo(client.id); //await: 얘가 다 수행될때까지 기다림

            if(userID) { //전달한 id가 UserStorage에 있으면
    
                if (userID === client.id && userPassword === client.psword) { //이 id와 client의 아이디 비교
                    return { success: true };
                }
                return { success: false, msg: "비밀번호가 틀렸습니다."};
            }
            return { success: false, msg: "존재하지 않는 아이디입니다."};

        } catch (err){
            return { success: false, msg: err };
        }
    }

    async register() {
        const client = this.body;
        try{ //async await 에러처리
            const response = await UserStorage.save(client); //회원가입 데이터 저장
            return response;
        } catch (err) {
            return {success: false, msg: err};
        }
    }
}

module.exports = User;
login() 함수 실행

4. UserStorage.js

"use strict";

//DB 불러옴
const db = require("../config/db");

class UserStorage {//데이터베이스

    //로그인
    static getUserInfo(id) {
        //데이터베이스 파일 읽기
        //Promise 안의 구문이 성공하면 resolve 실행, 실패하면 reject 실행
        return new Promise((resolve, reject) =>{
            const query = "SELECT * FROM USER WHERE userID = ?;"
            db.query( query ,[id], (err, data) => {
                if(err) reject(`${err}`);
                resolve(data[0]); //배열에서 패킷만 전달
            });
        });
    }

    //회원가입 데이터 넣기: 데이터 불러옴-> 추가할 데이터 추가 -> 데이터 저장
    static async save(userInfo) {
        return new Promise((resolve, reject) => {
            const query = "INSERT INTO USER(userID, userPassword, userName, userEmail) VALUES(?, ?, ?, ?);";
            db.query( query ,[userInfo.id, userInfo.psword, userInfo.name, userInfo.email], (err) => { //데이터는 받을 게 없음
                if(err) reject(`${err}`);
                resolve({ success: true }); //성공object 전달
            });
        });
    }
}

module.exports = UserStorage;
getUserInfo() 함수 실행 -> 데베에서 받은 데이터 Promise 형식으로 전달

5. login.js

"use strict";

//html에 입력된 아이디와 비밀번호를 js에서 제어해야함
//DOM-> javascript에서 html에 존재하는 데이터들을 기져와 제어할 수 있게하는 인터페이스 
//const id = document.querySelector("선택자");
const id = document.querySelector("#id"),
    psword = document.querySelector("#psword"),
    loginBtn = document.querySelector("#button");
    //registerBtn = document.querySelector("#registerbtn");

loginBtn.addEventListener("click", login);
//registerBtn.addEventListener("click", gotoregister);

function login() {
    const req = {
        id: id.value,
        psword: psword.value,
    };
    //console.log(req);
    //아이디, 비밀번호 서버에 전달
    //fetch(전달할 경로, 전달할 데이터)
    fetch("/user/login", {
        method: "POST", //body로 데이터 전달할 때는 POST로 전달해야함
        headers: {
            "Content-Type": "application/json",
        },
        body: JSON.stringify(req), //req를 JSON형태로 감싸줌
    })
        .then((res) => res.json()) //req해서 서버에서 보낸 res 받기
        .then((res) => {
            if(res.success){ //로그인 성공 시 루트로 이동
                location.href = "/";
            } else { //로그인 실패 시 실패 메세지 띄움
                alert(res.msg); 
            }
        })
        //에러처리
        .catch((err) => {
            console.error(new Error("로그인 중 에러 발생"));
        });
}
return값 받아서 success에 따라 기능 실행
Comments