그냥 값을 그대로 해싱하면 브루투포스 방법으로 알아낼 수도 있음
-> 랜덤한 salt를 뒤에 추가하여 암호화하면 알아내기 힘듦
-> 사용자마다 다른 랜덤한 salt 사용해야 의미가 있음!
-> 사용자마다의 발생된 salt를 db에 저장해두기(비밀번호와 물리적으로 다른 db에 저장)
mysql에 salt를 저장할 테이블 생성
create table UserSalt(
userid varchar(20) primary key,
salt varchar(500) not null
);
//////// mysql 연결
const mysql = require("mysql");
mysqlconn = mysql.createConnection({
host: "localhost",
user: "test",
password: "1234",
database: "myboard",
});
mysqlconn.connect();
console.log("mysqlconn ok ");
...
///// 회원가입 처리
const sha = require('sha256');
app.post("/signup", (req, res)=>{
console.log(req.body);
////// salt 생성 위한 부분 ///////////////
const crypto = require('crypto');
const generateSalt = (length = 16) => {
return crypto.randomBytes(length).toString('hex');
};// 16바이트의 hex 스타일로 랜덤 string 만들어기
const salt = generateSalt();
console.log(`Generated salt : ${salt}`);
////////////////////////////////////////
console.log(`salt 없는 pw hash: `, sha(req.body.userpw));
req.body.userpw = sha(req.body.userpw + salt);
console.log(`salt 있는 pw hash: `, req.body.userpw);
mydb.collection('account')
.insertOne(req.body)
.then(result => {
console.log('회원가입 성공');
//mysql에 salt 저장
const sql = `insert into UserSalt (userid, salt)
values (?, ?)`;
mysqlconn.query(sql, [req.body.userid, salt], (err, result2)=>{
if (err){
console.log(err);
}else{
console.log('salt 저장 성공');
}
});
})
.catch(err=>{
console.log(err);
});
res.redirect('/');
});
crypto
를 사용함app.post('/login', (req, res) =>{
//console.log(req.body);
mydb.collection('account')
.findOne({userid:req.body.userid})
.then(result => {
//console.log(result);
let salt;
const sql = `select salt from UserSalt
where userid=?`;
mysqlconn.query(sql, [req.body.userid], (err, rows, fields)=>{
console.log(rows);
salt = rows[0].salt;
});
// 입력한 pw를 hash로 변경
const hashPw = sha(req.body.userpw + salt);
if(result != null && result.userpw == hashPw){
//req.session.userid = req.body.userid;
req.body.userpw = hashPw;
req.session.user = req.body;
//console.log(req.session);
console.log('새로운 로그인');
//res.send(`${req.session.user.userid}님 환영합니다.`);
res.render('index.ejs', {user:req.session.user});
}else{
//res.send('login fail');
res.render('login.ejs');
}
})
.catch(err=>{
console.log(err);
res.status(500).send();
});
});
hashPw 설정하는 위치가 잘못됨!
sql 설정 안으로 넣어주어야 함
app.post('/login', (req, res) =>{
//console.log(req.body);
mydb.collection('account')
.findOne({userid:req.body.userid})
.then(result => {
//console.log(result);
let salt;
const sql = `select salt from UserSalt
where userid=?`;
mysqlconn.query(sql, [req.body.userid], (err, rows, fields)=>{
console.log(rows);
salt = rows[0].salt;
// 입력한 pw를 hash로 변경
const hashPw = sha(req.body.userpw + salt);
if(result != null && result.userpw == hashPw){
//req.session.userid = req.body.userid;
req.body.userpw = hashPw;
req.session.user = req.body;
//console.log(req.session);
console.log('새로운 로그인');
//res.send(`${req.session.user.userid}님 환영합니다.`);
res.render('index.ejs', {user:req.session.user});
}else{
//res.send('login fail');
res.render('login.ejs');
}
});
})
.catch(err=>{
console.log(err);
res.status(500).send();
});
});
npm i passport passport-local passport-facebook
server.js를 복사하여 server_local.js로 이름 변경
server_local.js
const passport = require('passport');
const localStragegy = require('passport-local').Strategy;
app.use(passport.initialize());
// req.session이 있는지 확인하고 존재하면 req.session.passport.user 추가
app.use(passport.session());
로그인해서 나온 객체를 세션에 할당해줌
app.post('/login',
passport.authenticate('local',{failureRedirect: '/fail'}),
(req,res)=>{
console.log(req.session);
console.log(req.session.passport);
res.render('index.ejs', {user:req.session.passport})
});
passport.use(new localStragegy(
{
usernameField: 'userid',
passwordField: 'userpw',
session: true,
passReqToCallback: false,
},
// 전략 수행 함수
function(inputid, inputpw, done){
mydb.collection('account')
.findOne({userid: inputid})
.then((result)=>{
if(result.userpw == inputpw){ // db == 입력값
console.log('새로운 로그인');
done(null, result);
}else{
done(null, false, {message: '비밀번호 틀렸어요'})
}
})
.catch();
}
))
~ 11:17
실행 후 로그인 시 에러 발생
serialize: 정보 객체가 저장되는 것
////////// passport local 사용 로그인
app.post('/login',
passport.authenticate('local',{
//successRedirect: '/',
//failureRedirect: '/fail'
}),
// 위 두 줄이 없어야 콜백함수로 들어갈 수도 있음
(req,res)=>{
console.log(req.session);
console.log(req.session.passport);
res.render('index.ejs', {user:req.session.passport})
});
...
passport.serializeUser(function(user, done){
console.log('serializeUser');
console.log(user);
done(null, user.userid);
});
passport.deserializeUser(function(puserid, done){
console.log('deserializeUser');
console.log(puserid);
mydb.collection('account')
.findOne({userid: puserid})
.then((result)=>{
console.log(result);
done(null, result);
})
.catch();
});
위 결과 설명 11:33~
done 끝나고 이 콜백? - post /login의 콜백
user 정보가 안뜸
c:/program files/openssl-win64/bin/
위 주소(openssl.cfg 있는 위치) 복사해서 환경변수 설정
접속 후 login 버튼 누르면