passport

이지우·2024년 6월 26일
0

멋사

목록 보기
13/16

비밀번호 암호화

salt 추가 hashing

그냥 값을 그대로 해싱하면 브루투포스 방법으로 알아낼 수도 있음
-> 랜덤한 salt를 뒤에 추가하여 암호화하면 알아내기 힘듦
-> 사용자마다 다른 랜덤한 salt 사용해야 의미가 있음!
-> 사용자마다의 발생된 salt를 db에 저장해두기(비밀번호와 물리적으로 다른 db에 저장)

salt 작업

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('/');
});
  • req.body로 입력 데이터가 넘어옴
  • salt를 문자열 형태로 생성
    -> 내장모듈 중 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 정보가 안뜸


https

c:/program files/openssl-win64/bin/
위 주소(openssl.cfg 있는 위치) 복사해서 환경변수 설정

접속 후 login 버튼 누르면


실습 과제

  • 06_26_pw_hashing 파일이용
  • userid 중복 검사 후 회원가입 되도록
profile
노력형 인간

0개의 댓글