md5보다 해싱을 많이한다. = 암호코드가 더 길어진다.
npm install sha256 --save
let sha256 = require('sha256');
3a7457085a9344ce3cf09f1a7cbc1b68
e4101c069aa8f0fd087d22016ea0394591e71924ff55f0aca8e3dcf1189849ae
e4101c069aa8f0fd087d22016ea0394591e71924ff55f0aca8e3dcf1189849ae
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
QfFt0KztuyADJ9nUYT+1aSSt4Qdg8mNnT9XvzUtsEB5sm2vRPVbYHfc82bK9zAn6QDG2boY/JTaXW1SP022ByQ==
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('비밀번호가 틀렸습니다.')
}
})
}
}
})
})
인증을 쉽게 구현할 수 있도록 고안한 모듈
세션베이스(식별자)
쿠키 : 로그인 했었다라는 정보 (세션아이디: 유니크)
JWT(Json Web Token)
open Authentication (OAuth)
타사 인증
비밀번호 다룰 필요 없음
npm install passport passport-local
// ────────────────── 패스포트를 이용한 인증 방식 ──────────────────
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('로그인 해주세요.');
}
}
<!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
require('dotenv').config()
코드 추가
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에 포함시켜서 보냄
<button class="input-group-append btn btn-danger" id="search">검색</button>
<script>
$('#search').click(function() {
window.location.replace('/url');
})
</script>
안녕하세요! 글 잘 읽었습니다!
그런데 저는 pbkdf2 해당 모듈 부분 사용해보니, 같은 salt값으로 로그인해도 hash값이 DB에 저장된 hash와 로그인시 hash가 다르게 나오는데 이런 현상 없으셨나요?