본문 바로가기

nodejs

노드js에서 로그인 기능 구현하기

728x90

Node.js와 Express를 사용하여 로그인 기능 만들기

npm install express-session

우선 터미널에서 express-session을 설치해 줍니다.

 

app.js에 세션을추가해 줍니다.

const session = require('express-session');
app.use(session({
  secret: 'your-secret-key',
  resave: false,
  saveUninitialized: true
}));

 

app.js

var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
const nunjucks = require('nunjucks');
const session = require('express-session');

var indexRouter = require('./routes/index');
// var usersRouter = require('./routes/users');

var app = express();

/** 세션 추가 */
app.use(session({
  secret: 'your-secret-key',
  resave: false,
  saveUninitialized: true
}));

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'njk');
nunjucks.configure('views', { 
  express: app,
  watch: true,
});

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', indexRouter);
// app.use('/users', usersRouter);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  next(createError(404));
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

module.exports = app;

 

 

main_modules > login.js

function login(req) {
    const id = 'z', pw = 'z', user_name = '유저닉네임';
    let login_auto = 0;
    try {
        const { userId, password, auto_login } = req.body;
        console.log(userId);
        console.log(userId.length);
        if (userId === id && password === pw) {
            const user_value = '암호화된 유저 정보';
            req.session.loggedIn = 1;
            auto_login ? login_auto = 1 : login_auto = 0;
            return {result : 1, user_value, login_auto, user_name, message : '로그인에 성공했습니다.'};
        } else {
            return {result : 0, message : '아이디나 비밀번호가 틀렸습니다.'};
        }
    } catch (error) {
        console.error(error);
        return {result : 3, message : '로그인하는데 문제가 발생했습니다.'};
    }
}

function logout(req) {
    req.session.destroy(err => {
        if (err) {
          console.error('세션 무효화 실패:', err);
          return res.status(500).json({result : 0, message: '로그아웃 실패' });
        }
    });
    return {result : 1, message : '로그아웃 되었습니다.'};
}

function login_verify(req) {
    const { user_value, auto_login } = req.body;
    let loggedIn = req.session.loggedIn;
    if (auto_login == 1) {
        loggedIn = req.session.loggedIn = 1;
    }
    return { loggedIn };
}

module.exports = {
    login, logout, login_verify
};

routes를 깔끔하게 유지하기 위해 로그인을 모듈로 만들었습니다.

세션의 loggedIn가 1이면 로그인 상태입니다.

login : 아이디와 비밀번호가 일치하면 세션에 등록 후 값을 반환합니다.

logout : 모든 세션을 삭제합니다. 다른방법으로는 loggedIn을 0으로 만드는 방법이 있습니다.

login_verify : 세션의 loggedIn 반환합니다. 처음 로그인할때 자동로그인에 체크했다면 로그인상태로 변환합니다.

 

index.js

var express = require('express');
var router = express.Router();
const {login, logout, login_verify} = require('../main_modules/login');

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index.html');
});

/** GET login page. */
router.get('/login', function(req, res, next) {
  res.render('login.html');
});

router.post('/login', function(req, res, next) {
  const xxx = login(req);
  res.json({xxx});
});

router.post('/logout', function(req, res, next) {
  const xxx = logout(req);
  res.json({xxx});
});

router.post('/login_verify', function(req, res, next) {
  const xxx = login_verify(req);
  res.json({xxx});
});

module.exports = router;

routes에서는 로그인 모듈의 값을 받아옵니다.

 

public > script > script_login.js

window.onload = function () {
function login_verify() {
fetch('/login_verify', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  }
})
.then(response => response.json())
.then(data => {
  if(data.xxx.loggedIn) {
    location.href = '/';
  }
})
.catch(error => {
  console.error('오류:', error);
});
}
login_verify();

const btn_login = document.getElementById('btn_login');
const message = document.getElementById('message');
function login() {
    const userId = document.getElementById('userId').value;
    const password = document.getElementById('password').value;
    const auto_login = document.getElementById('auto_login').checked;
    console.log(userId);
    console.log(password);
    console.log(auto_login);
    fetch('/login', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({ userId, password, auto_login })
      })
      .then(response => response.json())
      .then(data => {
        message.innerText = data.xxx.message;
        if (data.xxx.result === 1) {
          localStorage.setItem('user_value', data.xxx.user_value);
          localStorage.setItem('auto_login', data.xxx.login_auto);
          localStorage.setItem('user_name', data.xxx.user_name);
          location.href = '/';
        }
      })
      .catch(error => {
        console.error('오류:', error);
      });
}
btn_login.addEventListener('click', login);
}

로그인 페이지의 자바스크립트입니다.

현재 로그인상태인지 확인 후 로그인한 상태라면 메인화면으로 이동합니다.

아이디, 비밀번호, 자동로그인체크를 받아 로그인 처리 후 로컬스트리지에 저장 합니다.

 

public > script > script_main.js

window.onload = function () {
function login_verify() {
  const auto_login = localStorage.getItem('auto_login');
  const user_value = localStorage.getItem('user_value');
  fetch('/login_verify', {
  method: 'POST',
  headers: {
      'Content-Type': 'application/json',
  },
  body: JSON.stringify({ user_value, auto_login })
  })
  .then((response) => response.json())
  .then((data) => {
      const loggedIn = data.xxx.loggedIn;
      login_verifys(loggedIn);
  })
  .catch((error) => {
  console.error('오류:', error);
  });  
}

function login_verifys(loggedIn) {
  if (loggedIn === 1) {
    const user_name = localStorage.getItem('user_name');
    document.getElementById('login_check').innerText = user_name;
    document.getElementById('login_page').style.display = 'none';
    document.getElementById('btn_logout').style.display = 'block';
  } else {
    document.getElementById('btn_logout').style.display = 'none';
    document.getElementById('login_page').style.display = 'block';
  }
}

login_verify();


function logout() {
  localStorage.clear();
  fetch('/logout', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
  })
    .then((response) => response.json())
    .then((data) => {
      location.reload();
    })
    .catch((error) => {
      console.error('오류:', error);
    });
}
document.getElementById('btn_logout').addEventListener('click', logout);
}

메인화면 자바스크립트입니다.

로그인 상태를 확인 후 로그인했다면 로그아웃 버튼과 유저이름을 보여주고 로그인이 아니라면 로그인링크를 보여줍니다. 

로그 아웃 했다면 로컬스트리지에 저장된 정보를 모두 지웁니다.

 

 

index.html

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>메인화면</title>
  <link rel="stylesheet" href="../stylesheets/style.css">
  <script type="text/javascript" src="../script/script_main.js"></script>
</head>
<body>
<a href="/login" id="login_page">로그인</a>
<button type="button" id="btn_logout">로그아웃</button>
<div id="login_check"></div>
</body>
</html>

메인화면 html입니다.

 

login.html

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>로그인</title>
  <link rel="stylesheet" href="../stylesheets/style.css">
  <script type="text/javascript" src="../script/script_login.js"></script>
</head>
<body>
  <div class="container vertical">
    <div class="box">
      <input type="text" id="userId" placeholder="id" required>
      <input type="password" id="password" placeholder="Password" required>
      <div class="check">
      <input type="checkbox" id="auto_login"><label for="auto_login">자동 로그인</label>
      </div>
      <div><span id="message"><br></span></div>
      <button type="button" id="btn_login">Login</button>
    </div>
  </div>
</body>
</html>

로그인 html입니다.

 

node_express_login.zip
0.05MB

압축파일을 여기서 다운로드 받을 수 있습니다.

터미널에서 npm start로 실행 후 http://localhost:3000/ 로 접속해볼 수 있습니다.

아이디 : z   비밀번호 : z   입니다.

 

Error: Cannot find module 'http-errors' 오류가 뜬다면 node_modules 폴더가 없어서 뜨는 오류입니다.

터미널에 npm i http-errors입력 하면 필요한 모듈들을 다운로드 합니다.

728x90