[웹] 인증과 인가, 그리고 세션과 토큰 (feat. JWT)

Woonil·2025년 11월 13일
0

목록 보기
7/7

만화에 나오는 문구는 유튜브 '얄팍한 코딩사전'의 얄코님의 설명에서 가져왔다.

인증과 인가는 ‘사용자의 권한을 확인’하는 행위라는 비슷한 의미를 지니지만, 엄밀히 따지면 전혀 다른 정의를 가지고 있다.

  • 인증(Authentication): 사용자의 신원을 확인하는 과정
  • 인가(Authorization): 특정 데이터에 접근할 권한을 확인받는 과정

서비스의 보안을 위해서는 인증과 인가 모두 적절히 구현해야 한다. 오늘날 널리 통용되는 인증 방식으로는 세션 방식과 토큰 방식이 있다.

🤔개념

세션

세션 객체를 통해 인증을 처리하는 방식이다.

  • 특징
    • 서버에 정보를 저장한다.
    • 브라우저가 종료될 때까지 서버에 정보가 저장된다.
  • 장점
    • 서버에 저장되므로 브라우저에 저장되는 쿠키보다 보안성이 높다.
    • 세션 객체를 이용해 사용자들의 상태를 관리할 수 있다.
  • 단점
    • 세션
    • 세션 객체가 많아질수록 메모리가 과하게 사용될 수 있다.
    • 세션 객체가 많아질수록 데이터베이스 I/O가 잦아질 수 있다.
  • 활용방안
    • 현재 동시 접속자 수 계산
    • 유저 정보를 함께 저장하여 중복 로그인 제한

토큰

토큰을 이용해 인증을 처리하는 방식이다.

  • 장점
    • 데이터베이스 조회가 필요없다.
  • 단점
    • 사용자 상태를 관리할 수 없다.
    • 토큰 탈취 시 대처가 불가능하다.

JWT

JWT(Json Web Token)는 웹에서 사용되는 JSON 형식의 Claim 기반 웹 토큰에 대한 표준 규격으로, 주로 사용자 인증과 인가 정보를 서버와 클라이언트 간 안전하게 주고 받기 위해서 사용된다. 쿠키와 세션의 단점을 보완하기 위해 등장한 개념이기도 하다.

  • 구조: 하나의 JWT 토큰은 헤더, 페이로드, 서명 세 부분이 ‘.’ 기호로 구분되어 표현되며, 각각은 Base64 URL-safe Encode 방식을 통해 인코딩하여 직렬화한 것이다. [헤더].[페이로드].[시그니처]
    • 헤더: 토큰의 유형과 서명 알고리즘을 명시한다. 즉, 토큰 자체에 대한 정보를 담고있다.
    • 페이로드(내용): 사용자 인증/인가 정보를 저장한다.
    • 시그니처(서명): 헤더와 페이로드를 비밀키로 서명하여 저장하며, 토큰 위변조를 검사하는 데에 사용된다.
  • 장점
    • 서버에 세션을 저장할 필요가 없다.
    • 토큰 자체에 정보를 담고 있으므로, 쿠키를 지원하지 않는 환경에서도 유저 인증의 수단으로 사용될 수 있다.
  • 단점
    • 요청 시 쿠키의 값을 그대로 보내기 때문에 보안에 취약하다.
    • 용량 제한이 있어 많은 정보를 담을 수 없다.
    • 길이가 긴 편이라, 용량이 커질수록 네트워크에 부하가 심해진다.
    • 웹 브라우저마다 지원 형태가 다르기 때문에 브라우저 간 공유가 불가능하다.

jwt는 기밀성 보장?

jwt는 기밀성을 보장하는 것이 아닌 무결성을 보장하는 것이다. 따라서 세션보다 보안이 뛰어나다고 볼 수는 없다.

  • Access Token & Refresh Token: JWT의 시그니처로 인해 악의적인 사용자가 토큰의 페이로드를 변조하더라도 이는 웹 서버 측에서 검증할 수 있다. 하지만 토큰 자체를 탈취당한다면 말이 달라진다. 이러한 토큰의 단점을 어느정도 보완하기 위해 나온 개념이 Access Token과 Refresh Token이다.

    • Access Token: 실질적인 인증을 위한 JWT로 유효 기간이 매우 짧다.
    • Refresh Token: Access Token 만료 시 재발급을 위해 사용되어, Access Token의 짧은 유효 기간을 보완한다.

😎실습

Express에서 세션을 통한 인증 처리

페이지를 인증(authentication)된 사용자에 한해서만 보여줘야 하는 경우가 있다. 세션 객체 확인을 통해 로그인 정보가 없다면 사용자를 홈 화면과 같이 비인증 사용자도 접근할 수 있는 페이지로 돌려보내게 설계해보았다.

// 로그인 시 사용자 정보를 저장하는 세션(req.session.user)을 부여하는 로직이 존재하여야 함
// 세션 확인 미들웨어 정의
const requireLogin = (req, res, next) => {
  if (!req.session.user) {
    res.render("index.ejs", { data: { deniedAccess: true } });
  } else {
    next();
  }
};

module.exports = requireLogin;
// 로그인한 사용자들에게만 보이는 게시물 목록
const requireLogin = require("../utils/requireLogin");

router.use("/post/list", requireLogin);
profile
프론트 개발과 클라우드 환경에 관심이 많습니다:)

0개의 댓글