본문 바로가기
경일/nodejs

[node.js] fetch(async, await)로 로그인기능 만들어보기

by dev_kong 2022. 2. 15.
728x90
728x90

0. 목차

1. 개요

2. 기본세팅

3. HTML

4. fetch

5. 결과

1. 개요

수업시간에 ajax 비동기 통신에 대한 내용이 나와서 ajax 검색해보다가,

promise 를 리턴하는 fetch 문법 사용이 더 편리할것 같아서 fetch 문법 사용해봄

로그인 기능 만들거임

2. 기본세팅

const express = require('express');
const nunjucks = require('nunjucks');
const session = require('express-session');
const MemoryStore = require('memorystore')(session);
const fs = require('fs');

const userList = [
  {
    userid: 'kong1234',
    userpw: '1234',
    username: 'kong',
  },
  {
    userid: 'pea1234',
    userpw: '5678',
    username: 'pea',
  },
];

const sessionObj = {
  secret: 'kong',
  resave: false,
  saveUninitialized: true,
  store: new MemoryStore({ checkPeriod: 1000 * 60 * 10 }),
  cookie: {
    maxAge: 1000 * 60 * 10,
  },
};

const app = express();

app.use(express.json());

app.use(session(sessionObj));

app.set('view engine', 'html');
nunjucks.configure('views', { express: app });

데이터 베이스 연결하기 귀찮아서 그냥 가라데이터 입력해버림..ㅎ

3. HTML

 

<!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>Document</title>
  </head>
  <body>
    <h1>test</h1>
    <div id="content">
      <ul>
        <li>id : <input type="text" id="userid" /></li>
        <li>pw : <input type="text" id="userpw" /></li>
      </ul>
      <button onclick="onButtonClicked('/')">로그인</button>
    </div>
  </body>
</html>

 

index.html

 

<p>{{user.username}}님 환영합니다~</p>
<ul>
  <li><a href=""> profile </a></li>
  <li><a href=""> logout </a></li>
</ul>

successLogin.html

4. Api 설계

 

app.get('/', (req, res) => {
  const { user } = req.session;

  res.render('index.html', { user });
});

app.post('/user/login', (req, res) => {
  const { userid, userpw } = req.body;
  const user = userList.filter(
    (v) => v.userid === userid && v.userpw === userpw
  );
  if (user[0] !== undefined) {
    req.session.user = user[0];
    fs.readFile('./successLogin.html', 'utf-8', (err, result) => {
      if (err) return console.log(err);

      res.send(result);
    });
  } else {
    res.send('로그인 실패');
  }
});

 

로그인에 성공하면, successLogin 파일을 읽어서 result 로 받고 send 로 보내준다.

 

5. fetch

  async function onButtonClicked(url) {
      const userid = document.querySelector('#userid').value;
      const userpw = document.querySelector('#userpw').value;
      const content = document.querySelector('#content');

      const option = {
        method: 'post',
        headers: {
          'Content-type': 'application/json',
        },
        body: JSON.stringify({ userid, userpw }),
      };
      const response = await fetch('/user/login', option);
      const data = await response.text();
      content.innerHTML = data;
    }

버튼이 클릭되면 작동될 함수다.

fetch를 이용해서, async, await 으로 만들었다.

 

주의하며 봐야될건 option 부분

content-type 을 json 으로 지정했기 때문에

body에 보내주는 값 역시 json 으로 보내 줘야한다.

때문에 JSON.stringfy method를 사용했다.

 

headers 를 입력하지 않으면

자동으로 content-type 은 www-x-form-urlencoded 로 지정이 된다.

이럴경우는 boyd 에 입력되는 내용이 queryString으로 바뀌어야 한다.

body : `userid=${userid}&userpw=${userpw}`

 이렇게.

 

 

6. 결과

인생 뜻대로 안된다.

 

파일을 읽은 결과물을 data 변수에 담아서

innerhtml 로 넣어버리면,

html 태그들은 적용이 되지만,

nunjucks 부분은 적용이 되질 않아서,

{{user.name}} 이 그대로 랜더링 돼 버린다.

흠... 

아무리 고민해도 이부분을 해결을 못하겠다.

내일 물어봐야지...

 

블로그 다 쓰고 나서 갑자기 든 생각...

읽은 파일의 텍스트를 그냥 문자열로 생각하고 

메서드들로 작업하면 일단 결과는 원하는 대로 나오지 않을까....

 

<p>{{username}}님 환영합니다~</p>
<ul>
  <li><a href=""> profile </a></li>
  <li><a href=""> logout </a></li>
</ul>

이렇게 수정하고

 

app.post('/user/login', (req, res) => {
  const { userid, userpw } = req.body;
  const user = userList.filter(
    (v) => v.userid === userid && v.userpw === userpw
  );
  if (user[0] !== undefined) {
    req.session.user = user[0];
    fs.readFile('./successLogin.html', 'utf-8', (err, result) => {
      if (err) return console.log(err);

      const doingShit = result //
        .split('{{username}}')
        .join(user[0].username);

      res.send(doingShit);
    });
  } else {
    res.send('로그인 실패');
  }
});

 

이렇게 수정했다..ㅋㅋㅋㅋㅋㅋㅋ

split 으로 username 을 기준으로 배열로 나눌것이고,

join 으로 배열을 합칠때 username 을 넣어서 합친다....

ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ

 

ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ

되긴된다.. 당연히 이렇게 하는거 아니겠지.... ㅎ

 

한가지 더 방법이 있긴한데,

이건 진짜 아닌 것 같다..

 

app.post('/user/login', (req, res) => {
  const { userid, userpw } = req.body;
  const user = userList.filter(
    (v) => v.userid === userid && v.userpw === userpw
  );
  if (user[0] !== undefined) {
    req.session.user = user[0];
    res.send(user[0].username);
  } else {
    res.send('로그인 실패');
  }
});

res.send로 username 을 전달하고,

 

    async function onButtonClicked(url) {
      const userid = document.querySelector('#userid').value;
      const userpw = document.querySelector('#userpw').value;
      const content = document.querySelector('#content');

      const option = {
        method: 'post',
        headers: {
          'Content-type': 'application/json',
        },
        body: JSON.stringify({ userid, userpw }),
      };
      const response = await fetch('/user/login', option);
      const data = await response.text();

      content.innerHTML = `
      <p>${data}님 환영합니다~</p>
      <ul>
        <li><a href=""> profile </a></li>
        <li><a href=""> logout </a></li>
      </ul>
      `;
    }

data 로 받아서 

innerHTML에 하드코딩을 해버린다...!

ㅎㅎㅎ...

이건진짜 아니다라고 느끼는게

지금 내가 만든 건 꼴랑 몇줄이지만,

 

진짜 엄청 긴 HTML이라면 이렇게 하드코딩하는 방식은 진짜 너무너무너무 비효율적일것 같다..

이것보단 차라리 위에꺼가 더 좋은 방법이라는 생각이 든다.

728x90
728x90

댓글