Session으로 로그인 상태 저장하기

Kim-DaHam·2023년 5월 4일
0

Server

목록 보기
4/10
post-thumbnail

🔥 학습목표

  • Session을 사용하여 사용자의 로그인 상태를 저장한다.
  • 서버가 쿠키 대신 세션을 이용하도록 바꾼다.



🟩 Server

세션도 쿠키를 사용하긴 하지만, 유저 id를 직접 담는 게 아닌 서버에서 세션 id를 받아와 사용한다.

  • 서버는 세션 저장소에 세션을 저장한다.
  • 해당 세션 id를 암호화해서 클라이언트의 쿠키로 저장한다.
  • 요청이 올 때마다 쿠키에 있는 세션 id를 확인해서 유저인지 확인한다.

🟣 Express 서버 구축하기

⬜ 필요한 모듈

// 그 외 쿠키 실습과 동일
const session = require('express-session');
  • express-session : express에서 session을 사용할 수 있게 하는 패키지

⬜ 미들웨어 등록

app.use(
  session({
    secret: '@codestates',
    resave: false,
    saveUninitialized: true,
    cookie: {
      domain: 'localhost',
      path: '/',
      httpOnly: true,
      sameSite: 'strict',
    },
  })
);

🔵 미들웨어 사용 방법

  • session(options) : option과 함께 세션 미들웨어를 만든다.
    └▶ 세션 데이터는 그 자체로 쿠키로 저장되지 않고, sessionID만 저장된다. 세션 데이터는 서버측에서 저장한다.
    └▶ 1.5.0 버전부터 express-session 미들웨어 사용 시 cookie-Parser 미들웨어필요 없다. express-session 모듈이 직접적으로 req/res에서 쿠키를 가져와 읽어올 수 있다.
    └▷ 세션을 저장하는 default storage 는 인메모리 데이터 저장소이다.
    └▷ 인메모리는 데이터 누출이 발생하고 확장되지 않는다. (호환되는 세션 스토어를 찾아 쓰면 된다)

  • Options
    • cookie : 쿠키에 대한 설정을 한다.
      └▷ 기본값 : { path: '/', httpOnly: true, secure: false, maxAge: null }
    • genid : 세로운 세션 아이디를 생성하기 위해 함수를 호출하는 옵션.
    • name : 세션 아이디 쿠키의 이름.기본값은 connect.sid
    • proxy : 노드 서버가 프록시 뒤에 있다면 설정해주는 옵션
    • rolling : 로그인 상태에서 다른 페이지로 이동할 때마다 세션 값에 변화를 줄 것인지 결정
    • resave : 요청이 왔을 때 세션에 수정 사항이 생기지 않더라도 세션을 다시 저장할지 설정하는 옵션
    • saveUninitialized : 세션에 저장할 내용이 없더라도 처음부터 세션을 설정할지 결정.
    • secret : 쿠키에 서명을 추가하는 것. cookieParsersecret과 같게 설정하는 것이 좋다.
    • store : 외부 저장소에 연결할 때 사용. 레디스 같은 저장소를 연동할 수 있다.

🎁 express-session


🌠 쿠키의 secure 옵션이 true일 경우
Domain이 localhost 여도 https 서버를 실행해야 제대로 작동된다.
express-session을 사용하면서 http 서버에서 쿠키를 사용하려면 secure 옵션을 작성하지 않으면 된다.
단, 실제 배포 단계에서는 https 서버 사용과 동시에 secure 옵션이 설정되어 있어야 안전하다.


⬜ 요청 메서드 라우터

app.post('/login', controllers.login);
app.post('/logout', controllers.logout);
app.get('/userinfo', controllers.userInfo);



🟣 Controller

마찬가지로 이렇게 구성 되어있다.


⬜ 로그인 POST 요청

필요한 상태 관리

const { userId, password } = req.body.loginInfo;
  const { checkedKeepLogin } = req.body;
  • 클라이언트에서 POST 요청 시, loginInfo 객체에 유저 아이디와 비밀번호가 request body로 담겨 온다.

  • 로그인 유지 옵션을 체크했으면 true, 아니면 false 값이 넘어온다.


사용자 계정 데이터

const userInfo = {
    ...USER_DATA.filter((user) => user.userId === userId && user.password === password)[0],
  };

저장 된 회원 데이터 중 아이디와 비밀번호가 일치한 회원 정보를 불러온다.


주요 기능

여기서부터 쿠키 실습과 비교하면 좋다.

if (!userInfo.id) {
    res.status(401).send('Not Authorized');
  } else if (checkedKeepLogin) {
    req.session.userId = userInfo.id;
    req.session.cookie.maxAge = 24 * 6 * 60 * 10000;
    res.redirect('/userinfo');
  } else {
    req.session.userId = userInfo.id;
    res.redirect('/userinfo');
  }
  • 해당되는 유저가 없으면 401 에러 보내기.

  • 로그인 유지 체크 시 세션 데이터 userId, 쿠키 옵션의 maxAge를 설정한다.
    └▶ 세션에 데이터를 설정하면, 모든 세션이 설정되는게아니라, 요청 받은 고유의 세션 사용자의 값만 설정 된다.

  • 로그인 유지 체크를 하지 않은 사용자는 쿠키 옵션의 maxAge를 설정하지 않는다.(브라우저 종료 시 바로 삭제 되어야 하니까.)

  • 로그인한 사용자 정보를 불러오기 위해 /userinfo 경로로 리다이렉트 한다.


⬜ 유저 정보 GET 요청

유저 정보(비밀번호 제외) 전송하기

(req, res) => {
  const userInfo = USER_DATA.filter((user) => user.id === req.session.userId)[0];
  if (!userInfo) {
    res.status(401).send('Not Authorized');
  } else {
    res.json({ ...userInfo, password: undefined });
  }
};
  • 로그인 한 id와 세션 데이터 userId가 동일한 사용자 정보를 뽑아온다.

  • 정상적으로 존재한다면 비밀번호를 undefined 로 변경한 회원 정보를 응답으로 보내준다.


⬜ 로그아웃 POST 요청

세션 삭제

if (!req.session.userId) {
    res.status(400).send('Not Authorized');
  } else {
    req.session.destroy()
    res.status(205).send('Logged Out Successfully');
  }
  • session.destroy() - 세션을 삭제한다.

🎁 더 자세한 참고자료


profile
다 하자

0개의 댓글