lky473736 / forum-express

(project) Community and Forum Service with express.js and node.js
Apache License 2.0
0 stars 0 forks source link

forum-express : log 5_1 #8

Open lky473736 opened 5 months ago

lky473736 commented 5 months ago

forum-express : log 5_1

회원가입 및 로그인 기능을 구현한 코드 가이드라인을 정리한다.


로그인

// /login 페이지에 사용할 DB 탐색 함수 (passport)
// 사용 방식 : passport.authenticate('local')(~~~~~~~~)
passport.use(new LocalStrategy(async (입력아이디, 입력비밀번호, cb) => {
  try {
    let result = await db.collection('user').findOne({ username : 입력아이디});

    if (!result) {
      return cb(null, false, { message: 'DB에 account가 없음' });
    }

    // 해싱된 비밀번호와 입력한 비밀번호를 비교
    let isPassword = await bcrypt.compare(입력비밀번호, result.password);
    console.log(isPassword);

    if (isPassword) {
      return cb(null, result);
    } 

    else {
      return cb(null, false, { message: '비밀번호 불일치' });
  } } catch (err) {
    return 응답.status(500).send('DB error occurred');
  }
}));

// login 완료 후 session 발행
// 요청.logIn 사용할 때 자동 실행된다
// done 안에 두번째 인자 : session document, 쿠키에 담아서 유저에게 보내줌
passport.serializeUser((user, done) => {
  process.nextTick(() => {
    done(null, { id: user._id, username: user.username });
  });
});

// deserializeUser : 유저가 보낸 쿠키 분석 & session과 비교 (요청.user == 유저의 정보)
// 회원가입과 로그인 페이지 API를 맨 위로 보내기
passport.deserializeUser(async(user, done) => {
  let result = await db.collection('user').findOne({_id : new ObjectId(user.id)})
  delete result.password
  process.nextTick(() => {
    return done(null, result)
  })
});

// /login : 로그인 페이지
app.get ('/login', (요청, 응답) => {
  응답.render("login.ejs", {로그인상태 : 요청.user});
});

app.post ('/login', async(요청, 응답, next)=> {
  // 제출한 아이디와 비번 쌍이 DB에 있는 건지 확인
  // -> session 생성

  // 아래 과정은 base. passport 문법으로 구현
  // const user = await db.collection('user').findOne({
  //   username : 요청.body.username,
  //   password : 요청.body.password
  // });
  // if (user == null) {
  //   console.log("이런 회원 없음");
  // }
  // else {
  //   console.log("회원가입 성공");
  // }

  passport.authenticate('local', {sessions: false}, (error, user, info) => {
    if (error) { // 서버 에러남
      return 응답.status(500).send ("server error occured");
    }

    if (!user) { // 유저가 없음 or 비밀번호 불일치
      return 응답.status(401).json (info.message);
    }

    요청.logIn(user, (err) => { // logIn함수가 session을 만들어 준다
      if (err) { // 에러나면
        return next(err);
      }

      응답.redirect("/");
    });
  })(요청, 응답, next);
});

회원가입

// /register : 회원가입
app.get ('/register', async(요청, 응답) => {
  응답.render ("register.ejs", {로그인상태 : 요청.user});
});

app.post ('/register', async(요청, 응답) => {
  if (요청.body.username == '' || 요청.body.password == '') {
    응답.send("<script>alert('아이디나 비밀번호가 작성되지 않았습니다. 다시 작성해주십시오.'); window.location.replace('/auth');</script>");
  }

  else {
    try {
      // 비밀번호를 hashing해서 저장하기
      let hashingPassword = await bcrypt.hash(요청.body.password, 10);

      await db.collection('user').insertOne({
        username : 요청.body.username, // 아이디 넣기
        password : hashingPassword, // 비밀번호 넣기 (해싱된)
        name : 요청.body.name // 이름 넣기
      });

      응답.redirect ('/');
    } catch (err) {
      console.log(err);
      return 응답.status(500).send('server error occurred');
    }
  }
});