221123 Node.js #10

김혜진·2022년 11월 23일
0

Node.js

목록 보기
10/13

MySQL


단방향 암호화 기법

sha256

md5보다 해싱을 많이한다. = 암호코드가 더 길어진다.

npm install sha256 --save
let sha256 = require('sha256');

cmd 테스트

md5

3a7457085a9344ce3cf09f1a7cbc1b68

sha256

e4101c069aa8f0fd087d22016ea0394591e71924ff55f0aca8e3dcf1189849ae
e4101c069aa8f0fd087d22016ea0394591e71924ff55f0aca8e3dcf1189849ae

pbkdf2

npm install pbkdf2-password

해싱된 비밀번호의 길이가 길어질 것을 대비해 비밀번호 필드의 글자수를 늘려줌.
alter table login modify userpw varchar(10000);

app.post('/signup', (req, res) => { 

    hasher({password: req.body.pw}, function(err, pass, salt, hash) {
        console.log(pass);
        console.log(salt);
        console.log(hash);
        
        let sql = `insert into login (userid, userpw, mobile, country) values ( "${req.body.id}", "${hash}", "${salt}", "${req.body.country}" )`;

        conn.query(sql, function(err, rows, fields) {
            if(err) {
                console.log(err);
            } else {
                res.redirect('/login');
            }
        })
    });
})

입력한 비밀번호

1111

salt (내부적으로 생성)

QfFt0KztuyADJ9nUYT+1aSSt4Qdg8mNnT9XvzUtsEB5sm2vRPVbYHfc82bK9zAn6QDG2boY/JTaXW1SP022ByQ==

hash된 암호코드

a/nvK06zBINJZjLmKF/0gafhMOzy/GsRKPdLemwYf0ObWUCr8qQJIF7+Ffilh8IFZRjugUc51I0CZgBwmY8tjhLG65PPl6VylMtKfgll8tL+Mpdo40lJ63TRI+g/5srbVxual8qi+fM+BpKtCSlsNbNhGODH3kjppBEcK5k4ifQ=

데이터베이스에 저장된 모습

자동으로 만들어준 salt를 pw와 더해서 해싱을 하면 저장된 비밀번호를 찾아오지 못한다. 따라서 salt를 따로 저장을 해서 로그인 할 때마다 불러와 같은 값으로 더하게 하면 된다.

app.post('/login', (req, res) => {
    let userid = req.body.id;
    let userpw = req.body.pw;

    console.log(userid)
    console.log(userpw)

    let sql = "select * from login";
    conn.query(sql, function(err, rows, fields) {
        if (err) {
            console.log(err);
        }

        for (let i = 0; i < rows.length; i++) {

            if(rows[i].userid == userid) {
               return hasher({password: userpw, salt : rows[i].mobile}, function(err, pass, salt, hash) {
                console.log(pass);
                console.log(salt);
                console.log(hash);

                if(hash === rows[i].userpw) {
                    req.session.userid = userid;
                    res.redirect('/');
                }
                else {
                    res.send('비밀번호가 틀렸습니다.')
                }
               })

            }
        }
    })
})

MongoDB Atlas


회원 인증

패스포트 js

인증을 쉽게 구현할 수 있도록 고안한 모듈

auth 인증

  1. local 인증
  2. 타사 인증 : federation authentication

회원 인증 방법

  1. 세션베이스(식별자)
    쿠키 : 로그인 했었다라는 정보 (세션아이디: 유니크)

  2. JWT(Json Web Token)

  3. open Authentication (OAuth)
    타사 인증
    비밀번호 다룰 필요 없음

npm install passport passport-local

server.js

// ────────────────── 패스포트를 이용한 인증 방식 ──────────────────
app.post('/login', passport.authenticate('local', {
    failureRedirect : '/fail'
}), (req,res) => {
    res.redirect('/');
});

passport.use(new LocalStrategy({
    usernameField : 'id',
    passwordField : 'pw',
    session : true,
    passReqToCallback : false,
}, function(inputid, inputpw, done) {
    console.log(inputid);
    console.log(inputpw);

    db.collection('login').findOne({ id : inputid }, function(err, result) {
        if(err) return done(err);
        if(!result) {
            return done(null, false, {message : '존재하지 않는 아이디입니다.'});
        }
        if(result.pw == inputpw) {
            return done(null, result);
        }
        else {
            return done(null, false, {message : '비밀번호가 틀렸습니다.'});
        }
    })
}));

passport.serializeUser(function(user, done) {
    done(null, user.id);
});

passport.deserializeUser(function(userid, done) {
    db.collection('login').findOne({id: userid}, function(err, result) {
        if(err) return console.log(err);
        
        done(null, result);
        console.log(result);
    });
});


app.get('/fail', (req, res) => {
    res.send("로그인 해주세요.");
});

app.get('/mypage', isLogin, (req, res) => {
    res.render('mypage.ejs', {사용자 : req.user});
});

function isLogin(req, res, next) {
    if(req.user) {
        next(); // 다음으로 넘어감
    } else {
        res.send('로그인 해주세요.');
    }
}

mypage.ejs

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title></title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi" crossorigin="anonymous">
  </head>
  <body>
    <%- include('nav.html') %>

    <h1 class="ml-2 my-3 text-center"><%= 사용자.id %> 님의 마이페이지 입니다.</h1>
    
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-OERcA2EqjJCMA+/3y+gxIOqMEjwtxJY7qPCqsdltbNJuaOe923+mo//f6V8Qbsw3" crossorigin="anonymous"></script>
  </body>
</html>

로그인 시도 (DB와 정보가 맞으면)
⇒ 세션 정보를 만들어 쿠키에 저장
⇒ 마이페이지 (세션 검사)

미들웨어: 요청 / (미들웨어 : 필터링) / 응답


환경변수

npm install dotenv

server.js

require('dotenv').config()

코드 추가

.env

PORT = 9000
DB_URL = "mongodb+srv://admin:970604@cluster0.895rolx.mongodb.net/?retryWrites=true&w=majority"

환경변수 파일 생성

const mongoClient = require('mongodb').MongoClient;
app.set('view engine', 'ejs');

var db;
mongoClient.connect(
    process.env.DB_URL,

    function(err, client) {
    if(err) return console.log(err);

    db = client.db('TodoApp');

    app.listen( process.env.PORT, function() { // 8080 포트에 서버를 띄워라
        console.log('listening on 8080');
    })
})

포트 번호와 DB_URL 정보 불러오기


검색

쿼리스트링

app.get("/qtest", (req, res) => {
    res.send(req.query.id + ',' + req.query.pw);
})

get 요청으로도 서버에 데이터를 전달할 수 있는 방법
: url 1개 - 내가 전달하고 싶은 정보를 url에 포함시켜서 보냄

  1. 검색어 입력 후 검색 버튼 클릭 (쿼리스트링으로 데이터를 보낸다.)
  2. 서버는 DB에서 데이터를 꺼낸다.
    (collection.toArray()와 같은 방법 사용)
  3. 서버에서 ejs 결과를 보내주면 끝
      <button class="input-group-append btn btn-danger" id="search">검색</button>  

    <script>
      $('#search').click(function() {
        window.location.replace('/url');
      })
    </script>
profile
알고 쓰자!

1개의 댓글

comment-user-thumbnail
2022년 11월 30일

안녕하세요! 글 잘 읽었습니다!
그런데 저는 pbkdf2 해당 모듈 부분 사용해보니, 같은 salt값으로 로그인해도 hash값이 DB에 저장된 hash와 로그인시 hash가 다르게 나오는데 이런 현상 없으셨나요?

답글 달기