index.js 9.13 KB
const express = require('express');
const session = require('express-session');
const passport = require('passport'), LocalStrategy = require('passport-local').Strategy;
const fs=require('fs');
const router = express.Router()
const fileStore = require('session-file-store')(session);
const app = express();


//Middle Ware list
app.use(express.urlencoded({extended:false}));
app.use(session({
    secret: 'secret key',
    resave: false,
    saveUninitialized: false,
    store : new fileStore()
  }));
app.use(passport.initialize());
app.use(passport.session());



//사용자 정보 세션 읽기, 쓰기
passport.serializeUser(function(user, done) {   //쓰기
    done(null, user.email);
});

passport.deserializeUser(function(id, done) {   //읽기
    done(null, id);
});

//첫 페이지
app.get('/',(req,res)=>{
    let page = getFirstPage('Passport','This is Passport Example Page',authInfo(req));
    res.send(page);
});

//메인 페이지
//Express에서 정적파일(ex: main.html, main.js)들을 사용할경우
//경로를 미리 제시해 주는 부분
app.use(express.static(__dirname + '/main'));

app.get('/main',(req,res)=>{
    res.sendFile(__dirname+'/main/main.html')
})


//로그인 페이지
app.get('/login',(req,res)=>{
    let page =  getLoginButton(`<a href="/">뒤로가기</a>`);
    res.send(page);
});

//로그인 인증 (Passport)
passport.use(new LocalStrategy({
        //로그인 페이지 input 태그 내 name
        usernameField: 'email',
        passwordField: 'password'
    },
  (id, password, done)=>{
      console.log(id,password);
    //회원 정보가 한개이상 있을때
    if(user){
      console.log(user);

        //아이디가 다를때
        if (id !== user.email){  
            //alert("존재하는 아이디가 없습니다.")
            return done(null, false, { message: '아이디가 다르다' });}
        //비밀번호가 다를때
        else if (password !== user.password) {
            //alert("비밀번호가 다릅니다.");
            return done(null, false, { message: '비번이 다르다' });}
        //아이디, 비밀번호 모두 맞을 경우
        return done(null, user);
    }
}));

//로그인 처리 (Passport)
app.post('/login',
passport.authenticate('local', { 
    //성공시, 메인페이지 이동
    //실패시 로그인 페이지 이동
    successRedirect: '/',
    failureRedirect: '/login' 
}));


//회원가입 페이지 Get
app.get('/join',(req,res)=>{
  let page = getPage('',`
  <html>
  <head>
  <style>
  body {
    padding-top: 15px;
    font-size: 12px
  }
  .main {
    max-width: 320px;
    margin-top:300px auto;
    margin: 0 auto;
  }
  .login-or {
    position: relative;
    font-size: 18px;
    color: rgb(7, 7, 7);
    margin-top: 10px;
    margin-bottom: 10px;
    padding-top: 10px;
    padding-bottom: 10px;
  }
  .span-or {
    display: block;
    position: absolute;
    left: 50%;
    top: -2px;
    margin-left: -25px;
    background-color: #fff;
    width: 50px;
    text-align: center;
  }
  .hr-or {
    background-color: #cdcdcd;
    height: 1px;
    margin-top: 0px !important;
    margin-bottom: 0px !important;
  }
  h3 {
    text-align: center;
    line-height: 300%;
    margin-top:10px auto;
  }
  img{
      width:320px;
      height:150px;
      object-fit:cover;
      margin-bottom:30px;
  }
  </style><link href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
  <script> function congratulation()
      {
          alert("새로운 회원이 되신걸 축하합니다!:D \n 레시피 찾을 준비 되셨나요?");
      } </script>
</head>

  <body>
  <div class="container">
  <div class="row">
    <div class="main">
    <img src="https://images.unsplash.com/photo-1600577916048-804c9191e36c?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1632&q=80" alt=""/>
      <h3>Sign-Up</h3>
  <form action="/join" method="post">
  <div class="form-group">
      <input type="email" class="form-control" name="email" placeholder="email"><br>
  </div>
  <div class="form-group">
      <input type="password" name="password" class="form-control" placeholder="****"><br>
  </div>
  <div class="form-group">
      <input type="name" name="name" class="form-control" placeholder="이름"><br>
  </div>
      <button type="submit" value="회원가입" class="btn btn btn-primary" onClick="javascript:congratulation()">
      회원가입
      </button>
  </form>
  </html>
  `,'<a href="/login">뒤로가기</a>');
  res.send(page);
});

//회원가입 처리 Post : 예제를 위해 간단 저장 방식으로 구현
var user = {};
app.post('/join',(req,res)=>{
    user.email = req.body.email;
    user.password = req.body.password;
    user.name=req.body.name;
    //로그인 페이지로 이동
    res.redirect('/login');
});

//로그 아웃 처리
app.get('/logout',(req,res)=>{
    
    //passport 정보 삭제
    req.logout();
    //서버측 세션 삭제
    req.session.destroy(()=>{
        //클라이언트 측 세션 암호화 쿠키 삭제
        res.cookie('connect.sid','',{maxAge:0});
        res.redirect('/');
    });
});


//포트 연결
app.listen(3000,()=>console.log(`http://localhost:3000`));


//로그인 로그아웃 여부
const authInfo = (req)=>{
    if(req.user) return `${user.name} | <a href="/logout">로그아웃</a>`;
    return `<a href="/login">로그인</a>`;
}

//페이지 템플릿
const getPage = (title, content, auth) =>{
    return `
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Passport Example</title>
    </head>
    <body>
    ${auth}
        <h1>${title}</h1>
        <p>${content}</p>
    </body>
    </html>
    `;
}

//로그인 버튼
const getLoginButton = (auth) =>{
    return `
    <!DOCTYPE html>
    <html>
    <head>
    <style>
    body {
        padding-top: 15px;
        font-size: 12px
      }
      .main {
        max-width: 320px;
        margin-top:300px auto;
        margin: 0 auto;
      }
      .login-or {
        position: relative;
        font-size: 18px;
        color: rgb(7, 7, 7);
        margin-top: 10px;
        margin-bottom: 10px;
        padding-top: 10px;
        padding-bottom: 10px;
      }
      .span-or {
        display: block;
        position: absolute;
        left: 50%;
        top: -2px;
        margin-left: -25px;
        background-color: #fff;
        width: 50px;
        text-align: center;
      }
      .hr-or {
        background-color: #cdcdcd;
        height: 1px;
        margin-top: 0px !important;
        margin-bottom: 0px !important;
      }
      h3 {
        text-align: center;
        line-height: 300%;
        margin-top:10px auto;
      }
      img{
          width:300px;
          height:150px;
          object-fit:cover;
          margin-bottom:30px;
      }
      </style>
    <link href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
    <script src="//netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
    <script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
    <title><%= title %></title>
    </head>
    <body>
    ${auth}
    <div class="container">
    <div class="row">
      <div class="main">
      <img src="https://i.ibb.co/k2zSVcn/142437038-e7b564cb-978a-4018-8834-9984cc3b119e.png" alt=""/>
      <!--이미지 아래부분이 살짝 잘림 -->
      <!--로그인,회원가입버튼 오른쪽 맞추는게 더 깔끔할거같음 -->

        <h3>Login</h3>
        <form role="form" method="POST" action="/login">
          <div class="form-group">
            <label for="userId">아이디</label>
            <input type="text" class="form-control" id="email" name="email">
          </div>
          <div class="form-group">
            <label for="password">비밀번호</label>
            <input type="password" class="form-control" id="password" name="password">
          </div>
          <button type="submit" class="btn btn btn-primary">
            로그인
          </button>
            <button type="submit" class="btn btn btn-primary">
           <a href="/join" style="color:white;text-decoration-line:none;"> 회원가입</a>
        </form>
        
      </div>
    </div>
  </div>
</body>
</html>
    `;
}

//첫 페이지 화면
const getFirstPage =(title, content, auth) =>{
    return `
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Passport Example</title>
    </head>
    <body>
    ${auth}
        <h1>${title}</h1>
        <p>${content}</p>
        <div>
        <input type="button" value="page move" onClick="movepage()"/>
        </div>
        <script type="text/javascript">
        function movepage(){
            location.href="main";
        }</script>
    </body>
    </html>
    `;

}