Notice
Recent Posts
Recent Comments
Link
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

우당탕탕 개발일지

JWT 기반 인증 시스템 본문

Front-end/React

JWT 기반 인증 시스템

YUDENG 2023. 6. 4. 18:40
인증은 사용자의 신원을 확인하고, 인가는 인증된 사용자에 대한 권한에 따라 시스템에 접근하도록 허용한다. 인증은 인가 이전에 수행되고, 인증된 사용자에 대해서만 인가 절차가 진행된다.

 

인증

사용자가 자신의 신분을 확인하고 시스템에 대한 신뢰성을 보장하는 과정

 

인가

인증된 사용자가 시스템의 특정 자원에 접근하고 특정 작업을 수행할 수 있는지 여부를 결정하는 과정

 

 인증은 일반적으로 아이디와 비밀번호를 제공함으로써 로그인을 통해 수행된다. 그러나 작업 수행마다 아이디와 비밀번호를 보내는 방법은 매번 서버에서 확인을 해야할 뿐만 아니라 보안에 있어서도 취약하다는 문제가 있었고, 이를 위해 JWT가 나오게 되었다.

JWT

 JWT는 클라이언트와 서버 간의 정보를 안전하게 전송하기 위해 사용되는 인증 방식으로 헤더, 페이로드, 서명 세 부분으로 구성된다. 헤더와 페이로드는 코드화해서 누구나 디코딩할 수 있기에 중요한 정보를 포함하지 않아야 한다.

 

  • 헤더 : JWT의 타입과 해시 알고리즘 정보를 포함한다.
  • 페이로드 : JWT에 포함될 클레임(정보)들을 담고 있고, 클레임은 이름과 값 쌍으로 이루어져 있다.
  • 서명 : 헤더, 페이로드, 비밀 키를 사용하여 생성이 되며, JWT의 무결성을 검증하는 데 사용된다.

JWT 기반 인증 시스템

 JWT 기반 인증 시스템에서는 주로 액세스 토큰과 리프레시 토큰을 사용한다.

 

액세스 토큰 (Access Token)

사용자가 리소스에 접근하기 위해 사용되는 토큰으로, 클라이언트가 보유하고 API 서버에 제출하여 인증 및 권한 부여를 받는다. 주로 짧은 유효 기간을 가지며, 사용자 식별자, 권한 정보 등 필요한 클레임이 포함되어 있다.

 

리프레시 토큰 (Refresh Token)

액세스 토큰의 유효 기간이 만료되었을 때 새로운 액세스 토큰을 발급받기 위해 사용되는 토큰으로, 액세스 토큰보다 긴 유효 기간을 가진다. 액세스 토큰이 몇 분에서 몇 시간까지 유효 기간이 설정될 수 있다면, 리프레스 토큰은 몇 일에서 몇 주까지의 유효 기간이 설정될 수 있다. 유효 기간이 만료된 액세스 토큰과 리프레스 토큰을 함께 API 서버로 제출하면, API 서버는 리프레시 토큰을 검증하고 유효하면 새로운 액세스 토큰을 발급한다.

 

 이로써 사용자는 인증 과정을 거치지 않고 새로운 액세스 토큰을 얻을 수 있다. 리프레시 토큰은 클라이언트에게 안전하게 저장되어야 하며, 주로 쿠키에 저장된다.

JWT 사용 방식

  1. 클라이언트가 서버에 로그인 요청을 보낸다.
  2. 서버는 아이디, 비밀번호가 일치하는지 확인하고 액세스 토큰과 리프레시 토큰 모두 생성하고 클라이언트에게 전달한다. 액세스 토큰에는 아이디와 같은 유저 정보를 확인할 수 있는 정보가 들어가 있어야 한다.
  3. 클라이언트는 토큰을 저장하고 모든 작업 요청때마다 HTTP 헤더에 토큰을 담아 보낸다.
  4. 서버에서는 토큰을 복호화하여 유저 정보를 얻고, 데이터베이스에서 해당 유저의 권한을 확인한 후, 클라이언트의 요청을 처리하여 응답을 보내준다.
import { useState } from "react";
import { useNavigate } from "react-router-dom";
import axios from "axios";

interface postLoginReq {
  userId: String;
  password: String;
}

interface postLoginRes {
  accessToken: String;
  refreshToken: String;
}

export function Login() {
    const onLogin = async () => {
	const [userId, setUserId] = useState("");
	const [password, setPassword] = useState("");
	const navigate = useNavigate();
    
        const data: postLoginReq = {
          userId: userId,
          password: password,
        };
        
        try {
          const res = await axios.post<postLoginRes>("localhost:8080/login", data);

          //Access token
          const accessToken = res.data.accessToken;
          localStorage.setItem("accessToken", String(accessToken));

          //Refresh token
          const refreshToken = res.data.refreshToken;
          document.cookie = `refreshToken=${refreshToken}; path=/; secure; HttpOnly;`;
        } catch {
          alert("로그인에 실패하였습니다.");
        }
        
    	navigate(`/home`);
  };

위 코드는 JWT 기반 인증 시스템을 로그인 컴포넌트에 적용한 코드이다. 서버에 post 요청을 할 때는 유저 아이디와 비밀번호를 request 객체에 담아서 보낸다. 서버에서는 액세스 토큰과 리프레시 토큰을 response 객체에 담아서 보낸다. 클라이언트에서는 액세스 토큰을 localStorage에 저장하고, 리프레시 토큰을 쿠키에 저장한다.

728x90

'Front-end > React' 카테고리의 다른 글

Redux - 사용법  (0) 2023.08.05
Redux - 전역 상태 관리  (0) 2023.07.01
컴포넌트 내 데이터 전달  (0) 2023.06.01
useEffect  (0) 2023.05.21
Axios 사용법  (0) 2023.05.21