Node.js : DB 연동 - Passport 로그인 처리

Programming/Node.js 2019.03.10 03:49 Posted by 파란크리스마스

출처

/config/dbHelper.js

const mariadb = require('mariadb');
var config = require('./db_config');    // ./는 현재 디렉토리를 나타냅니다

const pool = mariadb.createPool({
    host: config.host,
    port: config.port,
    user: config.user,
    password: config.password,
    database: config.database,
    connectionLimit: 5
});

function dbHelper() {
    //
    this.getConnection = function(callback) {
        pool.getConnection()
            .then(conn => {
                callback(conn);
            }).catch(err => {
            //not connected
        });
    };

    //
    this.getConnectionAsync = async function() {
        try {
            let conn = await pool.getConnection();
            // console.log("conn = " + conn); // { affectedRows: 1, insertId: 1, warningStatus: 0 }
            return conn;
        } catch (err) {
            throw err;
        }
        return null;
    };

    //
    this.sendJSON = function(response, httpCode, body) {
        var result = JSON.stringify(body);
        response.send(httpCode, result);
    };
}

module.exports = new dbHelper();

/config/passport.js

var dbHelper = require('./dbHelper');
const LocalStrategy = require('passport-local').Strategy;

module.exports = (passport) => {

    // 로그인이 성공하면, serializeUser 메서드를 이용하여 사용자 정보를 Session에 저장할 수 있다.
    passport.serializeUser((user, done) => {
        console.log('serialize');
        done(null, user);
    });

    // 인증 후, 페이지 접근시 마다 사용자 정보를 Session에서 읽어옴.
    passport.deserializeUser((user, done) => {
        console.log('deserialize');
        done(null, user);
    });

    passport.use(new LocalStrategy({
            usernameField : 'userid',
            passwordField : 'password',
            passReqToCallback : true
        },

        // 인증 요청
        function(req, userid, password, done) {
            if(!userid || !password ) { return done(null, false, req.flash('message','All fields are required.')); }
            dbHelper.getConnection(function(conn) {
                console.log('conn = ' + conn);
                conn.query("select * from member where email = ?", [userid]).then((rows) => {
                    // console.log(rows);
                    if(!rows.length) {
                        return done(null, false, req.flash('message','Invalid username or password.'));
                    }
                    var dbPassword  = rows[0].password;
                    if(!(dbPassword == password)) {
                        return done(null, false, req.flash('message','Invalid username or password.'));
                    }
                    return done(null, rows[0]);
                })
                .then((res) => {
                    console.log('res = '+res); // { affectedRows: 1, insertId: 1, warningStatus: 0 }
                    conn.end();
                })
                .catch(err => {
                    //handle error
                    console.log(err);
                    conn.end();
                    if (err) return done(req.flash('message',err));
                });
            });
        }
    ));
};

웹페이지에 값 전달 (connect-flash 모듈)

/app.js

var flash = require('connect-flash');

app.use(passport.session()); //로그인 세션 유지
app.use(flash());

Node.js : MariaDB 연동

Programming/Node.js 2019.03.02 00:39 Posted by 파란크리스마스

출처

/config/db_config.js

module.exports = (function() {
    return {
        host: "localhost",
        port : 10312,
        user: "root",
        password: "sqldba",
        database: "simplesns"
    }
})();

/config/dbHelper.js

const mariadb = require('mariadb');
var config = require('./db_config');    // ./는 현재 디렉토리를 나타냅니다

const pool = mariadb.createPool({
    host: config.host,
    port: config.port,
    user: config.user,
    password: config.password,
    database: config.database,
    connectionLimit: 5
});

function dbHelper() {
    //
    this.getConnection = function(callback) {
        pool.getConnection()
            .then(conn => {
                callback(conn);
            }).catch(err => {
            //not connected
        });
    };

    //
    this.getConnectionAsync = async function() {
        try {
            let conn = await pool.getConnection();
            // console.log("conn = " + conn); // { affectedRows: 1, insertId: 1, warningStatus: 0 }
            return conn;
        } catch (err) {
            throw err;
        }
        return null;
    };

    //
    this.sendJSON = function(response, httpCode, body) {
        var result = JSON.stringify(body);
        response.send(httpCode, result);
    };
}

module.exports = new dbHelper();

/api/user/UserService.js

var dbHelper = require('../../config/dbHelper');

// https://github.com/jareddlc/node-datatables/blob/master/server.js
function UserService() {
    this.getUserList = function(request, response) {
        dbHelper.getConnection(function(conn) {
            conn.query('SELECT * FROM member')
                .then((results) => {
                    // console.log(results); //[ {val: 1}, meta: ... ]

                    //Output
                    var output = {};
                    var temp = [];
                    output.datas = results;
                    
                    dbHelper.sendJSON(response, 200, output);
                })
                .then((res) => {
                    console.log('res = '+res); // { affectedRows: 1, insertId: 1, warningStatus: 0 }
                    conn.end();
                })
                .catch(err => {
                    //handle error
                    console.log(err);
                    conn.end();
                })
        });
    }
}

module.exports = new UserService();

Node.js : Controller

Programming/Node.js 2019.03.02 00:16 Posted by 파란크리스마스

출처

/api/user/user.ctrl.js

/* api 로직 */
let users = [
    {id: 1, name: 'jinbro'},
    {id: 2, name: 'jinhyung'},
    {id: 3, name: 'park'}
];

let index = function(req, res) {
    if(!req.query.limit){
        res.json(users);
    } else {
        const limit = parseInt(req.query.limit, 10);

        if(isNaN(limit)){
            return res.status(400).end();
        }
        res.json(users.slice(0, limit));
    }
};

let read = function(req, res) {
    const id = parseInt(req.params.id, 10);

    console.log("id = " + id);

    if(isNaN(id)) {
        return res.status(400).end();
    }

    const user = users.filter((user) => {
        return user.id === id;
    })[0];

    if(!user) {
        return res.status(404).end();
    }

    res.json(user);
};

module.exports = {
    index: index,
    read: read
    //create: create,
    //update: update,
    //destroy: destroy
};

/api/user/index.js

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

const controller = require('./user.ctrl');

/* user 라우팅 로직 */
router.get('/', controller.index);
router.get('/:id', controller.read);
//router.post('/', controller.create);
//router.put('/:id', controller.update);
//router.delete('/:id', controller.destroy);

module.exports = router;

/app.js

/* use router class */
const user = require('./api/user/index.js');

/* /users 요청을 모두 /user/index.js로 */
app.use('/users', user);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  next(createError(404));
});

실행

Node.js 기초

Programming/Node.js 2019.03.01 19:33 Posted by 파란크리스마스

출처

변수

출처 : 2. 기초문법 · node.js 서버구축하기

var name; // 변수 선언
name = '홍길동'; // 변수 정의

var num2 = 3; // 변수 선언과 정의

함수

출처 : 함수 표현식 vs 함수 선언식 • Captain Pangyo

함수 선언식 - Function Declarations

// 함수 선언
function funcDeclarations() {
  return 'A function declaration';
}
funcDeclarations(); // 함수 호출

함수 표현식 - Function Expressions

// 함수 표현식 -> 함수 변수 선언
var funcExpression = function () {
    return 'A function expression';
}
funcExpression(); // 함수 호출

조건문

if < > && || ==

반복문

for, while

클래스

// User 클래스 선언
function User(_name){
    // 변수를 객체의 멤버로 사용하기 위해 this 예약어를 사용해서 정의
    this.name = _name; // 사용자 이름
    this.age = 0; // 사용자 나이

    // 사용자 이름을 반환 하는 User 클래스의 내장 함수
    this.getName = function() {
        return this.name;
    }

    this.getAge = function() {
        return this.age;
    }
}

var user1 = new User("bluexmas"); // User 객체 생성 
console.log(user1.getName()); // User 클래스의 내장 함수 호출

prototype

// User객체의 prototype을 가져와서 setAge 함수 추가
User.prototype.setAge = function(_age){
    this.age = _age;
}

user1.setAge(10);
console.log(user1.getAge()); // User 클래스의 내장 함수 호출

require - 동적 라이브러리 로딩

출처 : Node.js 기초와 모듈 (내장 모듈, npm, 사용자정의 모듈)

url 모듈을 이용해서 url 파싱하는 예제

var url = require("url");
var parsedURL = url.parse("http://www.example.com/profile?name=barry");
 
console.log(parsedURL.protocol); // "http:"
console.log(parsedURL.host); // "www.example.com"
console.log(parsedURL.query); // "name=barry"

Node.js : Passport를 이용한 사용자 인증

Programming/Node.js 2019.02.16 19:18 Posted by 파란크리스마스

출처

/app.js

// 모듈 추가
const passport = require('passport');
const session = require('express-session');
var bodyParser = require('body-parser');

// ... 생략 ...

/*
cookieParser
session
passport.initialize
passport.session
app.route
 */
var app = express();

// ... 생략 ...

app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

// 세션 설정
app.use(session({
  secret: 'simpleSNS',
  resave: true,
  saveUninitialized: false
})); // 세션 활성화

require('./config/passport')(passport);
app.use(passport.initialize());
app.use(passport.session()); //로그인 세션 유지

app.use(bodyParser.urlencoded({extended: true}));

/public/login.html

<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>
<form action="/login" method="post">
    <div>
        <label>UserId:</label>
        <input type="text" name="userid"/><br/>
    </div>
    <div>
        <label>Password:</label>
        <input type="password" name="password"/>
    </div>
    <div>
        <input type="submit" value="Submit"/>
    </div>
</form>
</body>
</html>

/config/passport.js

const LocalStrategy = require('passport-local').Strategy;

module.exports = (passport) => {

    // 로그인이 성공하면, serializeUser 메서드를 이용하여 사용자 정보를 Session에 저장할 수 있다.
    passport.serializeUser((user, done) => {
        console.log('serialize');
        done(null, user);
    });

    // 인증 후, 페이지 접근시 마다 사용자 정보를 Session에서 읽어옴.
    passport.deserializeUser((user, done) => {
        console.log('deserialize');
        done(null, user);
    });

    passport.use(new LocalStrategy({
            usernameField : 'userid',
            passwordField : 'password',
            passReqToCallback : true
        },
        
        // 인증 요청
        function(req, userid, password, done) {
            if(userid=='test' && password=='1111') {
                var user = {
                    'userid':'hello',
                    'email':'hello@world.com'
                };
                return done(null, user);
            }else{
                return done(null, false);
            }
        }
    ));
};

/routes/index.js

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

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });
});

// 로그인
router.post('/login', passport.authenticate('local', {failureRedirect: '/login.html'}), (req, res) => {
  res.redirect('/login_suc.html');
});

/*
router.post('/login', passport.authenticate('local', {
  successRedirect: '/login_suc.html',
  failureRedirect: '/login.html'
}));
*/

// 로그아웃
router.get('/logout', (req, res) => {
  req.logout();
  res.redirect('/');
});

module.exports = router;

Facebook 로그인 적용

/config/passport.js 내용 추가

const FacebookStrategy = require('passport-facebook').Strategy;

module.exports = (passport) => {

// ... 생략 ...

    passport.use(new FacebookStrategy({
            clientID: "",
            clientSecret: "",
            profileFields: ['id', 'displayName', 'photos'],
            callbackURL: 'http://localhost:3000/markdown/auth/facebook/callback'
        },

        function (accessToken, refreshToken, profile, done) {
            const socialId = profile.id;
            const nickname = profile.displayName;
            const profileImageUrl = profile.photos[0].value;

            onLoginSuccess('Facebook', socialId, nickname, profileImageUrl, done);
        }
    ));

/routes/index.js 내용 추가

// ... 생략 ...

// 로그아웃
router.get('/logout', (req, res) => {
  req.logout();
  res.redirect('/');
});

// 페이스북 로그인 시작
router.get('/facebook', passport.authenticate('facebook'));

// 페이스북 로그인 결과 콜백
router.get('/facebook/callback', passport.authenticate('facebook', {
    failureRedirect: '/markdown/auth/login'
}), (req, res) => {
    loginSuccessHandler(req, res);
});

module.exports = router;

WebStorm : express 프로젝트 생성

Programming/Node.js 2019.02.16 19:09 Posted by 파란크리스마스

출처

프로젝트 생성

express 프로젝트 생성

express 프로젝트 실행

실행결과

Node.js 8.x 설치 설치

Programming/Node.js 2019.01.26 13:13 Posted by 파란크리스마스

출처

Node.js 8.x 설치

$ curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
$ sudo apt-get install -y nodejs

Node.js 버전 확인

$ node --version
v8.15.0

Express 설치

$ sudo npm install -g express
+ express@4.16.4
added 48 packages from 36 contributors in 16.445s

Express 애플리케이션 생성기 설치

$ sudo npm install express-generator -g
/usr/bin/express -> /usr/lib/node_modules/express-generator/bin/express-cli.js
+ express-generator@4.16.0
added 10 packages from 13 contributors in 5.69s

Express 애플리케이션 만들기

$ express myapp
 
  warning: the default view engine will not be jade in future releases
  warning: use `--view=jade' or `--help' for additional options
 
 
   create : myapp/
   create : myapp/public/
   create : myapp/public/javascripts/
   create : myapp/public/images/
   create : myapp/public/stylesheets/
   create : myapp/public/stylesheets/style.css
   create : myapp/routes/
   create : myapp/routes/index.js
   create : myapp/routes/users.js
   create : myapp/views/
   create : myapp/views/error.jade
   create : myapp/views/index.jade
   create : myapp/views/layout.jade
   create : myapp/app.js
   create : myapp/package.json
   create : myapp/bin/
   create : myapp/bin/www
 
   change directory:
     $ cd myapp
 
   install dependencies:
     $ npm install
 
   run the app:
     $ DEBUG=myapp:* npm start

Express 애플리케이션 초기화

$ cd myapp
$ sudo npm install
audited 194 packages in 9.077s
found 2 low severity vulnerabilities
  run `npm audit fix` to fix them, or `npm audit` for details

Express 애플리케이션 실행

$ DEBUG=myapp:* npm start
 
> myapp@0.0.0 start /home/pi/workspace/myapp
> node ./bin/www
 
  myapp:server Listening on port 3000 +0ms
GET / 200 2337.812 ms - 170
GET /stylesheets/style.css 200 28.972 ms - 111
GET /favicon.ico 404 165.796 ms - 1062

브라우져로 확인

Node.js - Windows에 설치

Programming/Node.js 2017.07.09 19:13 Posted by 파란크리스마스

출처 : [nodejs] 윈도우에서 node.js 설치 및 실행하기 - 워크식스 블로그

PATH에 추가

C:\server\node-v6.11.2-win-x64

Hello world

C:\> node
>
(To exit, press ^C again or type .exit)
> console.log('hello world!')
hello world!
undefined

웹서비스

// 모듈을 추출합니다.
var http = require('http');

// 웹 서버를 만들고 실행합니다.
http.createServer(function (request, response) {
  response.writeHead(200, { 'Content-Type': 'text/html' });
  response.end('<h1>Hello World!</h1>');
}).listen(80, function () {
  console.log('Server running at http://127.0.0.1/');
});

실행

C:\> node http_test.js