JWT(Access Token)

무과장·2023년 8월 28일
0

JWT란?

JWT(Json Web Token)는 클라이언트와 서버 간에 정보를 안전하게 전송하기 위한 개방형 표준입니다. 사용자 인증 정보를 포함하며, 해당 정보는 디지털 서명에 의해 검증될 수 있다.

JWT의 장점

-스테이트리스(Stateless): JWT는 요청이 독립적으로 서버에서 처리될 수 있도록 설계되었다. 즉, 서버는 클라이언트 상태를 기억할 필요가 없으며, 이로 인해 확장성이 뛰어나고 서버 부하를 줄일 수 있다..


-Self-contained: JWT는 필요한 모든 정보를 자체적으로 지니고 있다. JWT는 이 정보를 안전하게 전달하기 위해 디지털 서명된다.


-인증 및 교차 도메인 인증 정보 교환 용이: JWT는 사용자의 인증 정보를 가지고 있으므로, 웹사이트나 모바일 앱에서 로그인 세션을 유지하거나 API에서 사용자를 인증하는 등의 용도로 사용될 수 있다.

JWT의 단점

-크기: JWT는 많은 양의 메타 데이터를 포함하며, 세션 ID와 비교했을 때 상대적으로 크다. 따라서, 네트워크에서의 오버헤드를 증가시킬 수 있다.


-데이터 보안성: 페이로드(Payload) 정보는 기본적으로 암호화되지 않습니다. 따라서 중요한 개인 데이터가 포함되지 않도록 주의해야 한다. 또한, 토큰이 탈취되면 사용자의 정보가 노출될 수 있으므로 보안에 신경을 써야 한다.


-삭제가 어려움: JWT는 서버에서 발행되고 나면 만료되기 전까지는 클라이언트에서 계속 사용될 수 있다. 이는 로그아웃 또는 즉각적인 토큰 만료에 문제를 일으킬 수 있다.

authentication(인증) : 쉽게 말해 로그인, 내가 이 곳의 사용자임을 인증


authorization(인가) : 인증 받은 사용자가 내 계정으로만 할 수 있는 활동을 시도할 때, 로그인이 되고 나서 일어나는 일들


stateless : 이처럼 시간에 따라 바뀌는 어떤 상태 값을 안 갖는 걸 말함.

JWT를 이용한 로그인 시스템 구축 로직

  1. 사용자 인증: 사용자가 로그인 페이지에서 이메일, 비밀번호 등을 입력하고 '로그인' 버튼을 클릭하면, 이 정보는 서버로 전송된다. 서버는 이 정보를 데이터베이스와 비교하여 사용자를 인증한다.

  2. 토큰 생성: 사용자가 성공적으로 인증되면, 서버는 해당 사용자에 대한 JWT를 생성한다. 이 토큰에는 사용자 식별 정보(ID 등)가 포함되며, 이 정보는 비밀 키를 사용해 서명된다.

  3. 토큰 전송: 생성된 JWT는 사용자에게 응답으로 전송된다. 일반적으로 이 토큰은 HTTP 응답의 헤더 또는 바디에 포함되어 전송된다.

  4. 토큰 저장 및 사용: 클라이양트(브라우저나 앱)는 전달받은 JWT를 저장(일반적으로 로컬 스토리지나 쿠키)하고, 이후 서버에 요청할 때마다 이 토큰을 HTTP 요청 헤더에 포함시켜 인증 정보를 제공한다.

  5. 토큰 검증: 서버는 클라이언트의 요청을 받을 때마다 헤더에서 JWT를 추출하여, 서명을 확인함으로써 토큰의 유효성을 검증한다. 토큰이 유효하다면 요청을 처리하고, 그렇지 않다면 에러 메시지를 반환한다.

  6. 로그아웃 및 토큰 만료: 사용자가 로그아웃하면 클라이언트는 저장된 JWT를 제거한다. 또한, JWT에는 만료 시간(expiration)이 설정되어 있어 일정 시간이 지나면 자동으로 만료된다. 이 경우 사용자는 다시 로그인하여 새로운 토큰을 받아야 한다.
  1. 로그인 요청을 한다.
  2. 일치하면 Access Token 받아온다.
  3. Access Token를 변수에 저장한다.
  4. 변수를 HTTP request header에 추가해 API 요청을 한다.
  //사용자 로그인
  const onSubmitHandlerForAdmin = async (data: IFormInput) => {
    // Basic Authentication을 위한 header 설정
    const auth = "Basic " + btoa(data.Username + ":" + data.Password);
    await apiLogin
      .post(
        "/admins/login",
        {},
        {
          headers: {
            Authorization: auth,
          },
        }
      )
      .then((response) => {
        localStorage.setItem("tokenForAdmin", response.data.accessToken);
        localStorage.setItem("refreshToken", response.data.refreshToken);
        setTokenForAdmin(response.data.accessToken);
        alert("로그인 성공!");

        navigate("/Home");
      })
      .catch((error) => {
        alert("로그인 실패...");
      });
  };
profile
느리더라도 꾸준히 확실하게.

0개의 댓글