로그인 - 세션 기반 인증 방식

이강용·2024년 6월 24일
0

CS

목록 보기
66/109

세션 기반 인증 방식

  • HTTP의 주요 특징 중 하나는 Stateless(무상태)하다는 것
  • 이는 각 HTTP 요청이 독립적이며 요청 간에 상태 정보가 유지되지 않는다는 것을 의미
    • 예를들어, 사용자가 로그인 요청을 보내고 나면 서버는 다음 요청이 동일한 사용자로부터 왔는지 알지 못함, 요청이 끝나면 사용자 정보나 상태는 서버에 남지 않기 때문에 매번 새로운 요청처럼 처리됨
  • 이러한 무상태 특성 때문에 웹 애플리케이션은 사용자의 로그인 상태를 유지하기 위해 추가적인 방법이 필요한데, 이를 해결하기 위해 세션 기반 인증 방식이 사용됨

용어 정리

세션 : 서버와 클라이언트의 연결이 활성화된 상태
세션 ID : 웹 서버 또는 DB에 저장되는 클라이언트에 대한 유니크 ID


1. 로그인 요청(Login Request)
- 클라이언트 : 사용자가 로그인 페이지에서 사용자명과 비밀번호를 입력하고
  이를 포함한 POST 요청을 서버로 전송
  
  POST /login
  username=david
  password=davidh
  
2. 서버 인증(Server Authentication)
- 서버 : 사용자가 보낸 자격 증명을 확인
  데이터베이스를 참조하여 사용자명과 비밀번호가 일치하는지 검증
  - 인증 성공 시 : 
    1. 세션 ID를 생성
    2. 생성된 세션 ID를 쿠키에 담아 클라이언트로 반환
    3. 세션 ID와 관련된 세션 데이터를 DB에 저장
  
3. 세션 ID 설정(Set Session ID)
- 서버 : 생성된 세션 ID를 클라이언트로 전송
  이때, HTTP 응답 헤더에 Set-Cookie를 사용하여 세션 ID를
  클라이언트의 쿠키에 저장하도록 지시

  Set-Cookie: SESSIONID=86C530ACAF44D1B05588019ECBC0C737C
  
4. 클라이언트의 세션 ID 저장(Cient Stores Session ID)
- 클라이언트 : 클라이언트 브라우저는 서버로부터 받은 세션 ID를 쿠키에 저장

5. 인증된 요청 처리(Handling Authenticated Requests)
- 클라이언트 : 사용자가 인증된 상태에서 서버에 요청을 보낼 때마다, 
  브라우저는 자동으로 쿠키에 저장된 세션 ID를 포함하여 서버로 전송
  
  Cookie: SESSIONID=86C530ACAF44D1B05588019ECBC0C737C

6. 세션 검증(Session Validation)
- 서버 : 요청에 포함된 세션 ID를 확인
  1. 세션 ID가 데이터베이스에 저장된 세션 데이터와 일치하는지 확인
  2. 세션이 유효한지(예: 만료되지 않았는지) 검증
  - 유효한 세션일 경우 : 요청을 처리하고, 해당 사용자의 데이터를 반환

7. 컨텐츠 제공(Providing Content)
- 서버 : 세션 검증이 완료되면, 요청된 컨텐츠를 클라이언트로 전송

실습

npm install escape-html express express-session

// 사용자가 보낸 값을 보안을 위해 escape하기 위한 모듈입니다. // 예를 들어 foo & bar >> foo & bar 로 바꿉니다.
const escapeHtml = require("escape-html");
const express = require("express");
const session = require("express-session");
const app = express();

// 9e8821c8ef4ab43ba09310af54e98caedc13e314efdea720bf513b9b3675faf4
app.use(
  session({
    name: "session-id",
    secret: "9e8821c8ef4ab43ba09310af54e98caedc13e314efdea720bf513b9b3675faf4",
    resave: false,
    saveUninitialized: false,
  })
);
// 미들웨어 : auth
const isAuthenticated = (req, res, next) => {
  // 만약 세션이 있다면 다음 미들웨어로. 그게 아니라면. 다음 route로 제어권을 넘깁니다.
  if (req.session.user) next();
  else next("route");
};
// 만약 isAuthenticated 하다면 logout을 보여준다.
app.get("/", isAuthenticated, function (req, res) {
  res.send(escapeHtml(req.session.user) + "님 환영합니다!");
});
// 만약 isAuthenticated 하지 않다면 login을 보여준다.
app.get("/", function (req, res) {
  res.send(
    '<p>로그인</p><form action="/login" method="post">' +
      'Username: <input name="user"><br>' +
      'Password: <input name="pass" type="password"><br>' +
      '<input type="submit" text="Login"></form>'
  );
});
// 로그인요청 >> 세션 생성
app.post(
  "/login",
  express.urlencoded({ extended: false }),
  function (req, res) {
    if (req.body.user === "leesfact" && req.body.pass === "1234") {
      req.session.regenerate(function (err) {
        if (err) next(err);
        // input : user 에 있는 값을 req.session.user에 할당
        req.session.user = req.body.user;
        // 세션 생성 >> 쿠키값 설정 >> 이후 다시 리다이렉팅
        req.session.save(function (err) {
          if (err) return next(err);
          res.redirect("/");
        });
      });
    } else res.redirect("/");
  }
);
app.listen(3000, () => console.log("server is started :http://localhost:3000"));

profile
HW + SW = 1

0개의 댓글