Nodejs

 

 

인프런 강의

https://www.inflearn.com/course/node-js-%EC%9B%B9%EA%B0%9C%EB%B0%9C#

 

 

Node.js, Express를 기반으로 한 웹애플리케이션 구축.
Template Engine
Ajax와 JSON을 활용한 RESTful API 기반 웹 서비스 기초.
Passport기반의 인증처리 방법.


소스코드 : https://github.com/crongro/node_server_inflearn
https://github.dev/braverokmc79/node_server_inflearn

 

1. nodeJS + Express 웹서버 설정
1) NPM Project 시작하기
2) Express 기반 웹서버 구동
3) URL Routing 처리
4) static 디렉토리 설정

 

2. Request,Response 처리 기본
5) POST 요청처리
6) View engine을 활용한 응답처리
7) JSON 활용한 Ajax처리
중간 실습 과제 1

 

3. Database 연동 기본
8) MySQL 연동 설정
9) MySQL 연동 구현

 

4. Router 개선 - 모듈화
10) Routing 모듈화
11 )Routing 모듈화 2 (DB연결부분)
12) Routing 리팩토링

 

5. DB에 데이터추가
13) DB에 데이터추가 (create user) 1편
14) DB에 데이터추가 (create user) 2편
15) DB에 데이터추가 (create user) 3편


6. 패스포트기반 인증 로직 구현 (회원가입, 로그인, 로그아웃)
16) passport 환경구축
17) middleware,strategy 설정
18) passport 기반 router 설정
19) local-strategy 콜백완성
20) passport기반 세션처리
21) 로그인 로직 구현
22) Ajax 기반의 passport 인증처리
23) 로그아웃 처리
중간 실습 과제 2


7. RESTful API
24) RESTful API 정의
25) RESTful API GET
26) RESTful API POST
27) RESTful API GET SUB-URI
38) RESTful API DELETE

 

 

 

6. 패스포트기반 인증 로직 구현 (회원가입, 로그인, 로그아웃)

 

 

 

16) passport 환경구축

 

강의:  https://www.inflearn.com/course/node-js-%EC%9B%B9%EA%B0%9C%EB%B0%9C/unit/6140?tab=curriculum

 

 

설치 

$ npm install passport passport-local  express-session connect-flash 


 

passport 공식문서

https://www.passportjs.org/tutorials/password/signup/

https://github.com/jaredhanson/passport

 

 

app.js

const express = require('express');
const app = express();
const router = require("./router");
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const session = require('express-session');
const flash = require('connect-flash');


app.use(express.static("public")); //static 파일 등록 처리
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.set('view engine', 'ejs');
app.use(router);

app.listen(3000, function () {
    console.log("start! express server on port 3000");
});

 

 

 

 

 

 

17) middleware,strategy 설정

 

 

강의:   https://www.inflearn.com/course/node-js-%EC%9B%B9%EA%B0%9C%EB%B0%9C/unit/6141?tab=curriculum

 

app.js

const express = require('express');
const app = express();
const router = require("./router");
const passport = require('passport');
const session = require('express-session');
const flash = require('connect-flash');

app.use(express.static("public")); //static 파일 등록 처리
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.set('view engine', 'ejs');

app.use(session({
    secret: '1123@2312dajfj23rj2po4$#%@#',
    resave: false,
    saveUninitialized: false
}));


app.use(passport.initialize());//패스포트 초기화
app.use(passport.session());
app.use(flash());

app.use(router);




app.listen(3000, function () {
    console.log("start! express server on port 3000");
});

 

 

router/join/join.js

const express = require('express');
const passport = require('passport');
const router = express.Router();
const path = require("path");
const db = require("../../lib/db");
const LocalStrategy = require('passport-local').Strategy;

router.get("/", function (req, res) {
    console.log("join page  ...");
    res.render("join.ejs");
});


router.post("/", function (req, res) {
    const name = req.body.name;
    const email = req.body.email;
    const password = req.body.password;

    db.query("INSERT INTO users(name, email, password) VALUES (?, ? ,? )", [name, email, password], function (err, rows) {
        if (err) throw err;
        else res.render("welcome.ejs", { id: rows.insertId, name: name });
    });

});

passport.use('local-join', new LocalStrategy({
    usernameField: 'email',
    passwordField: 'password',
    passReqToCallback: true
}, function (req, email, password, done) {
    console.log('local-join callback called');
}
));



module.exports = router;

 

 

 

 

 

 

18) passport 기반 router 설정

 

강의:   https://www.inflearn.com/course/node-js-%EC%9B%B9%EA%B0%9C%EB%B0%9C/unit/6142?tab=curriculum

app.js

const express = require('express');
const app = express();
const router = require("./router");
const passport = require('passport');
const session = require('express-session');
const flash = require('connect-flash');

app.use(express.static("public")); //static 파일 등록 처리
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.set('view engine', 'ejs');

app.use(session({
    secret: '1123@2312dajfj23rj2po4$#%@#',
    resave: false,
    saveUninitialized: false
}));


app.use(passport.initialize());//패스포트 초기화
app.use(passport.session());
app.use(flash());

app.use(router);


app.listen(3000, function () {
    console.log("start! express server on port 3000");
});

 

 

router/join/join.js

const express = require('express');
const passport = require('passport');
const router = express.Router();
const path = require("path");
const db = require("../../lib/db");
const LocalStrategy = require('passport-local').Strategy;

router.get("/", function (req, res) {
    console.log("join page  ...");
    res.render("join.ejs");
});

passport.use(new LocalStrategy({
    usernameField: 'email',
    passwordField: 'password',
    passReqToCallback: true
}, function verify(req, email, password, done) {
    console.log('local-join callback called');
    console.log(email, password, done);
}
));

// 로그인 처리 - 1) 성공 및 실패 페이지 설정 및 flash 사용여부 설정하기
router.post('/', passport.authenticate('local', {
    successRedirect: '/passport/welcome',
    failureRedirect: '/passport/login',
    failureFlash: true,
    successFlash: true
}));

// router.post("/", function (req, res) {
//     const name = req.body.name;
//     const email = req.body.email;
//     const password = req.body.password;

//     db.query("INSERT INTO users(name, email, password) VALUES (?, ? ,? )", [name, email, password], function (err, rows) {
//         if (err) throw err;
//         else res.render("welcome.ejs", { id: rows.insertId, name: name });
//     });

// });


module.exports = router;

 

 

 

 

 

 

19) local-strategy 콜백완성

 

강의:   https://www.inflearn.com/course/node-js-%EC%9B%B9%EA%B0%9C%EB%B0%9C/unit/6143?tab=curriculum

 

router/join/join.js

const express = require('express');
const passport = require('passport');
const router = express.Router();
const path = require("path");
const db = require("../../lib/db");
const LocalStrategy = require('passport-local').Strategy;

router.get("/", function (req, res) {
    let msg = "";
    const errMsg = req.flash("error");
    if (errMsg) msg = errMsg;

    res.render("join.ejs", { 'message': msg });
});

passport.use(new LocalStrategy({
    usernameField: 'email',
    passwordField: 'password',
    passReqToCallback: true
}, function verify(req, email, password, done) {
    console.log("파라미터 ", req.body);

    db.query("SELECT * FROM users WHERE email=?", [email], function (err, rows) {
        if (err) return done(null, false, { message: err.toString() });

        if (rows.length) {
            console.log("existed email");
            return done(null, false, { message: "your email is already used" });

        } else {
            db.query("INSERT INTO users(name, email, password) VALUES (?, ? ,? )", [req.body.name, email, password], function (err, rows) {
                if (err) throw err;
                return done(null, { 'email': email, "name": req.body.name, "id": rows.insertId });
            });
        }


    });
}
));

// 로그인 처리 - 성공 및 실패 페이지 설정 및 flash 사용여부 설정하기
router.post('/', passport.authenticate('local', {
    successRedirect: '/main',
    failureRedirect: '/join',
    failureFlash: true,
    successFlash: true
}));



module.exports = router;

 

 

 

views/join.esj

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Join</title>
    <style>
        .messages{
            color: #963b3b;;
            margin-bottom: 16px;
        }
    </style>
</head>
<body>
    <h1>Join my website!</h1>
    <section class="messages"><%= message %></section>
    <form action="/join" method="post">
        email :  <input type="text" name="email"><br/>
        name :  <input type="text" name="name"><br/>
        password :  <input type="password" name="password"><br/>
        <input type="submit">
    </form>   
</body>
</html>

 

 

 

 

 

 

20) passport기반 세션처리

 

강의:   https://www.inflearn.com/course/node-js-%EC%9B%B9%EA%B0%9C%EB%B0%9C/unit/6144?tab=curriculum

 

회원 가입 페이지

views/join.ejs

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Join</title>
    <style>
        .messages{
            color: #963b3b;;
            margin-bottom: 16px;
        }
    </style>
</head>
<body>
    <h1>Join my website!</h1>
    <section class="messages"><%= message %></section>
    <form action="/join" method="post">
        email :  <input type="text" name="email"><br/>
        name :  <input type="text" name="name"><br/>
        password :  <input type="password" name="password"><br/>
        <input type="submit">
    </form>   
</body>
</html>

 

 

회원 가입 처리

router/join/join.js

const express = require('express');
const passport = require('passport');
const router = express.Router();
const path = require("path");
const db = require("../../lib/db");
const LocalStrategy = require('passport-local').Strategy;

router.get("/", function (req, res) {
    let msg = "";
    const errMsg = req.flash("error");
    if (errMsg) msg = errMsg;

    res.render("join.ejs", { 'message': msg });
});


passport.serializeUser(function (user, cb) {
    process.nextTick(function () {
        console.log("로그인 처리시 최초 한번만 실행 passport.serializeUser  :", user);
        cb(null, { id: user.id, email: user.email, name: user.name });
    });
});

// 로그인 성공되면 passport.deserializeUser  매번 실행 처리된다
passport.deserializeUser(function (user, cb) {
    process.nextTick(function () {
        console.log(" passport.deserializeUser  :", user);
        return cb(null, user);
    });
});


passport.use(new LocalStrategy({
    usernameField: 'email',
    passwordField: 'password',
    passReqToCallback: true
}, function verify(req, email, password, done) {
    console.log("파라미터 ", req.body);

    db.query("SELECT * FROM users WHERE email=?", [email], function (err, rows) {
        if (err) return done(null, false, { message: err.toString() });

        if (rows.length) {
            console.log("existed email");
            return done(null, false, { message: "your email is already used" });

        } else {
            db.query("INSERT INTO users(name, email, password) VALUES (?, ? ,? )", [req.body.name, email, password], function (err, rows) {
                if (err) throw err;
                return done(null, { "id": rows.insertId, 'email': email, "name": req.body.name });
            });
        }


    });
}
));

// 회원가입 처리 - 성공 및 실패 페이지 설정 및 flash 사용여부 설정하기
router.post('/', passport.authenticate('local', {
    successRedirect: '/main',
    failureRedirect: '/join',
    failureFlash: true,
    successFlash: true
}));



module.exports = router;

 

 

회원가입 성공시 이동처리

router/min/main.js

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


router.get("/", function (req, res) {
    console.log(" main js loaded    ");
    //res.sendFile(path.join(__dirname, "../../public/main.html"));
    console.log(" req.user  : ", req.user);
    res.render("main.ejs", { "user": req.user });
});

module.exports = router;

 

 

 

회원가입 성공시 이동 화면

views/main.ejs

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>main.html</title>
</head>
<body>
    <h1>메인 페이지</h1>
    <img src="images/crong.jpg" width="300" >
    
    <h2>welcome, <%= user.name %> !! </h2>
    
    <p><a href="/form.html">이메일 폼</a></p><br/>
    <p><a href="/join">회원가입</a></p>

    <script src="main.js"></script>
</body>
</html>

 

 

 

 

 

 

 

21) 로그인 로직 구현

 

강의:   https://www.inflearn.com/course/node-js-%EC%9B%B9%EA%B0%9C%EB%B0%9C/unit/6145?tab=curriculum

 

router/login/login.js

const express = require('express');
const passport = require('passport');
const router = express.Router();
const path = require("path");
const db = require("../../lib/db");
const LocalStrategy = require('passport-local').Strategy;

router.get("/", function (req, res) {
    let msg = "";
    const errMsg = req.flash("error");
    if (errMsg) msg = errMsg;
    res.render("login.ejs", { 'message': msg });
});


passport.serializeUser(function (user, cb) {
    process.nextTick(function () {
        console.log("로그인 처리시 최초 한번만 실행 passport.serializeUser  :", user);
        cb(null, { id: user.id, email: user.email, name: user.name });
    });
});

// 로그인 성공되면 passport.deserializeUser  매번 실행 처리된다
passport.deserializeUser(function (user, cb) {
    process.nextTick(function () {
        console.log(" passport.deserializeUser  :", user);
        return cb(null, user);
    });
});


passport.use(new LocalStrategy({
    usernameField: 'email',
    passwordField: 'password',
    passReqToCallback: true
}, function verify(req, email, password, done) {
    console.log("파라미터 ", req.body);

    db.query("SELECT * FROM users WHERE email=?", [email], function (err, rows) {
        if (err) return done(null, false, { message: err.toString() });

        if (rows.length) {
            console.log("existed email");
            return done(null, false, { message: "your email is already used" });

        } else {
            db.query("INSERT INTO users(name, email, password) VALUES (?, ? ,? )", [req.body.name, email, password], function (err, rows) {
                if (err) throw err;
                return done(null, { "id": rows.insertId, 'email': email, "name": req.body.name });
            });
        }


    });
}
));

// 회원가입 처리 - 성공 및 실패 페이지 설정 및 flash 사용여부 설정하기
router.post('/', passport.authenticate('local', {
    successRedirect: '/main',
    failureRedirect: '/join',
    failureFlash: true,
    successFlash: true
}));



module.exports = router;

 

 

 

views/login.ejs

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>로그인</title>
    <style>
        .messages{
            color: #963b3b;;
            margin-bottom: 16px;
        }
    </style>
</head>
<body>
    <h1>로그인</h1>
    <section class="messages"><%= message %></section>
    <form action="/join" method="post">
        email :  <input type="text" name="email"><br/>    
        password :  <input type="password" name="password"><br/>      
    </form>  
    
    <button class="ajaxsend">로그인</button>

    <script>
     document.querySelector('.ajaxsend').addEventListener('click',function(){
            var email =document.getElementsByName("email")[0].value;
            var password =document.getElementsByName("password")[0].value;
            sendAjax('/login/ajax',{'email':email, 'password':password});
        });
       
        function sendAjax(url, data){
            fetch(url, {
                headers:{'Content-Type' :"application/json"},
                method:"POST",
                body:JSON.stringify(data)
            }) .then(res=>res.json())  
            .then(res=>{
                console.log(" res :  ", res);

                const resultDiv=document.querySelector(".result");

                if(res.result!=="ok")return resultDiv.innerHTML="your email is not found";
                else resultDiv.innerHTML=res.name;
            }).catch(err=>console.error("에러:",err));
        }

    </script>
    
</body>
</html>

 

 

 

 

 

 

22) Ajax 기반의 passport 인증처리

 

강의:   https://www.inflearn.com/course/node-js-%EC%9B%B9%EA%B0%9C%EB%B0%9C/unit/6146?tab=curriculum

 

 

router/login/login.js

const express = require('express');
const passport = require('passport');
const router = express.Router();
const path = require("path");
const db = require("../../lib/db");
const LocalStrategy = require('passport-local').Strategy;

router.get("/", function (req, res) {
    let msg = "";
    const errMsg = req.flash("error");
    if (errMsg) msg = errMsg;
    res.render("login.ejs", { 'message': msg });
});


passport.serializeUser(function (user, cb) {
    process.nextTick(function () {
        console.log("로그인 처리시 최초 한번만 실행 passport.serializeUser  :", user);
        cb(null, { id: user.id, email: user.email, name: user.name });
    });
});

// 로그인 성공되면 passport.deserializeUser  매번 실행 처리된다
passport.deserializeUser(function (user, cb) {
    process.nextTick(function () {
        console.log(" passport.deserializeUser  :", user);
        return cb(null, user);
    });
});


passport.use(new LocalStrategy({
    usernameField: 'email',
    passwordField: 'password',
    passReqToCallback: true
}, function verify(req, email, password, done) {

    console.log("로그인 처리 파라미터 ", req.body);

    db.query("SELECT * FROM users WHERE email=? and password=?", [email, password], function (err, rows) {
        if (err) return done(null, false, { message: err.toString() });

        if (rows.length) {
            console.log("로그인 성공 처리 : ", rows[0]);
            return done(null, { "id": rows[0].id, "email": rows[0].email, "name": rows[0].name });

        } else {
            return done(null, false, { "message": "your login info is not found >.<" })
        }
    });
}

));



// ajax 로그인 처리
router.post('/', function (req, res, next) {

    passport.authenticate('local', function (err, user, info) {
        if (err) res.status(500).json(err);
        if (!user) return res.status(401).json(info.message);

        console.log("1.ajax 로그인 처리 :", user, info);

        req.logIn(user, function (err) {
            if (err) return next(err);
            return res.json(user);
        })

    })(req, res.next);


});



module.exports = router;

 

 

 

views/login.ejs

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>로그인</title>
    <style>
        .messages{
            color: #963b3b;;
            margin-bottom: 16px;
        }
    </style>
</head>
<body>
    <h1>로그인</h1>
    <h2 class="result"></h2>
    
    <section class="messages"><%= message %></section>
    <form action="/join" method="post">
        email :  <input type="text" name="email"><br/>    
        password :  <input type="password" name="password"><br/>      
    </form>  
    
    <button class="ajaxsend">로그인</button>

    
    <script>
     

     document.querySelector('.ajaxsend').addEventListener('click',function(){
            var email =document.getElementsByName("email")[0].value;
            var password =document.getElementsByName("password")[0].value;
            sendAjax('/login',{'email':email, 'password':password});
        });
       
        function sendAjax(url, data){
            fetch(url, {
                headers:{'Content-Type' :"application/json"},
                method:"POST",
                body:JSON.stringify(data)
            }) .then(res=>res.json())  
            .then(res=>{
                console.log(" res :  ", res);

                const resultDiv=document.querySelector(".result");
                if(!res.name)return resultDiv.innerHTML="아이디 또는 비밀번호가 일치하지 않습니다. ";
                else resultDiv.innerHTML=`${res.name}님! 환영합니다.`;

            }).catch(err=>   console.error("에러", err));
        }

    </script>
    
</body>
</html>

 

 

 

 

 

 

 

23) 로그아웃 처리

 

강의:   https://www.inflearn.com/course/node-js-%EC%9B%B9%EA%B0%9C%EB%B0%9C/unit/6147?tab=curriculum

 

 

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


//로그 아웃 처리
router.get('/', function (req, res, next) {
    req.logout(function (err) {
        if (err) { return next(err); }
        req.session.destroy(function (err) {
            res.redirect("/");
        });
    });
});


module.exports = router;

 

 

router/index.js

const express = require('express');
const router = express.Router();
const path = require('path');
const mainRouter = require("./main/main");
const emailRouter = require("./email/email");
let joinRouter = null;
let loginRouter = null;
const logoutRouter = require("./logout/logout");
const parseurl = require('parseurl');


router.get("/", function (req, res) {
    console.log("index");
    // res.sendFile(path.join(__dirname, "../public/main.html"));
    res.render("main.ejs", { user: req.user });
});


router.use(function (req, res, next) {
    const pathname = parseurl(req).pathname;
    console.log("현재 경록 :", pathname);

    if (pathname && pathname === "/login") {
        loginRouter = require("./login/login");
        router.use("/login", loginRouter);
    }

    if (pathname && pathname === "/join") {
        joinRouter = require("./join/join")
        router.use("/join", joinRouter);
    }
    next();
})



router.use("/main", mainRouter);
router.use("/email", emailRouter);
router.use("/logout", logoutRouter);


module.exports = router;


 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

about author

PHRASE

Level 60  라이트

부모를 왕위에 나아가게 한다해도 그 은혜는 다 갚지 못한다.-석가모니

댓글 ( 4)

댓글 남기기

작성