React : Refresh Token &Access Token& Cookie(브라우저 저장소)

2023. 10. 8. 14:47·React

1. Access Token

Access Token은 말 그대로 인증, 인가 서비스를 구현하기 위한 것이다.

  • 사용자가 로그인을 하면 백엔드 서버에서 토큰을 만들어 헤더에 담아 클라이언트에 전송한다.
  • 클라이언트는 서버에 요청(axios, fetch)을 할 때 서버로부터 받았던 토큰을 함께 전송한다.
  • 서버는 요청과 토큰을 함께 받고 서버에서 토큰을 디코딩하여 로그인한 사용자를 확인한다.

Access Token은 한 번 발급되면 강제로 만료 시킬 수 없다는 단점이 있다. 따라서 만료 시칸이 짧은 Refresh Token을 나눠서 사용한다.

 

2.Cookie

쿠키는 브라우저의 저장소 역할을 한다. 쿠키는 만료 기한이 있는 Key-value 저장소이다. 쿠키 또한 자바스크립트로 접근이 가능하지만, HTTP ONLY 옵션?을 설정하여 JS로 접근하는 것을 방지할 수 있다. 쿠키에 Access Token과 Refresh Token을 담으면된다. 

3.Refresh Token

Refresh Token은 Access Token의 유효기간을 짧게 하여 보안을 강화하면서도 사용자가 자주 로그아웃 되지 않도록 하는 목적으로 등장했다.

 

Refresh Token을 어디에 저장하는 것이 효율적이고 안전한지에 대해 가장 좋은 방법은 db에 저장하는 것이다.

Refresh Token값을 db에 저장하고, 클라이언트는 인덱스 값을 쿠키나 로컬 스토리지에 저장한다. 쿠키에 저장하는 경우, 만료 기간을 길게 잡으면 충분히 끊임 없이 로그인 된 상태를 유지할 수 있다. 인덱스 값도 사용자의 아이디나 추가 값을 조합하여 해시로 생성하여 사용하면 보안 측면에서 더 유리하다. 

 

Oauth2.0에서의 refresh Token

 

access token은 수명이 정해져 있다. (1시간, 2시간 등등)

수명이 끝나면 API에 접속했을 때 API는 정보를 주지 않는다. 이때마다 access token을 다시 발급 받아야하는데 사용자가 그 과정을 다시 거치게 하는 것은 힘

든일이다. 이런 경우에 손쉽게 access token을 발급 받을 수있는게 refresh token이다. 

 

 

oauth2.0 RFC

  •  (A):  client가 server에 Authorization Grant를 한다.
  •  (B):  Authorization server가 client에게 access token과 refresh token을 준다.
  •  (C):  Client는 이 두개를 저장해놓고 있다가 Access token을 제출함으로써 resource server에 있는 resource를 가져온다.
  •  (D): 보호되고 있는 자원을 client에 넘겨준다(프로필, 이메일)
  •  (E): 유효하지 않은 토큰 에러: access token의 수명이 끝났다. 
  •  (F): client는 이 때 refresh token을 전송하여 access token을 새로 발급 받는다.  

 

client_id

redirect_uri

auth_uri

-> 이 세가지는 .env 파일에 따로 보관하여 안전하게 보관한다.

 

 

프론트엔드의 역할(ex 카카오)

 

전반적인 과정

1. 사용자가 버튼을 누르면 로그인 화면 띄우기

2. 카카오에게 인가 코드(authorization code) 받아오기

3.인가 코드는 주소의 쿼리스트링에 담아져서 제공된다. 이걸 파싱해서 백엔드에게 전달한다.

4.(백엔드는 우리가 준 코드를 알아서 처리해서 )access token을 준다.

5. 그 토큰을 받아서 로그인을 유지한다. 

 

이때 access token과 refresh token은 local storage or cookie에 보관

 

1. 사용자가 버튼을 누를 시 플랫폼의 로그인 링크로 연결하여 로그인 화면 띄우기

 

 

카카오 공식문서

프론트에서 버튼을 만들고 이 버튼을 플랫폼 로그인 링크(KAKAO_AUTH_URL)와 연결한다.

위의 다이어그램에서 1. GET/oauth/authorize의 과정이다. 

이때 Rest_api_key와 redirect_uri는 노출이 되면 안되므로 .env파일에 저장해야한다.

 

 

 

   const Rest_api_key = process.env.REACT_APP_KAKAO_REST_API_KEY;
   const redirect_uri = process.env.REACT_APP_KAKAO_REDIRECT_URI;
   const KAKAO_AUTH_URL = `https://kauth.kakao.com/oauth/authorize?client_id=${Rest_api_key}&redirect_uri=${redirect_uri}&response_type=code`;

 

 

 

 

window.location.href를 이용해 주소를 연결해주면된다 .

 

 

 const handleLogin = () => {
        window.location.href = KAKAO_AUTH_URL;
    };

 

 

2. 카카오에게 인가 코드 받아오기

1번으로 만들어진 로그인 버튼을 클릭하면 카카오 계정 정보를 입력할 수 있는 창이 뜬다. 사용자가 정보를 모두 입력하고 동의하면 카카오는 Redirect URI로 인가코드를 전달한다. 크롬 주소창을 보면 카카오에서 준 인가코드가 보일 것이다. 

여기서 추가로 scope와 authuser, hd, prompt의 정보를 확인할 수있다. 

 

 

 

백엔드에서 받은 REDIRECT_URI 뒤에 code?=d@#@##$@라고 되어 있는 이 부분이 바로 카카오에서 주는 인가 코드이다. 이걸 백엔드한테 넘겨주면 백엔드에서 처리하는 부분은 ( 인가 코드를 카카오 인가 서버에 전달, 카카오는 인가 코드를 확인한 후 일치하면 백엔드에 토큰 넘겨줌, 카카오에서 받은 토큰을 유저 정보를 활용하여 우리 서버 전용 토큰으로 바꾼 후 프론트가 토큰 요청시(사용자가 재 로그인) 제공)이다. 프론트엔드는 이 토큰을 넘겨 받아 잘 보관하고 있다가, 사용자가 로그인을 하려하면 토큰을 다시 백엔드로 넘겨주면 된다. 

 

3. 인가 코드 주소 파싱한 후 백엔드에게 전달하기

파싱 해서 백엔드에게 전달하기 위해선 파싱하는 코드도 필요하다. 페이지: kakao/callback에서 받은 인가 코드를 백엔드에 전달할 페이지를 만든다. 

그럼 이제 새로 만든 페이지에서 인가코드를 파싱한 후 백엔드에 전달하면된다.

일단 주소창에 있는 코드를 받아와야 한다.  이때 code에 담기는 것은  인가 코드 자체가 아닌 쿼리 스트링 형태이다. 

 

따라서 아래와 같은 코드로 인가 코드만 파싱하면 된다.

 

 

const code = new URL(dococument.location.toString()).searchParams.get('code');

 

 

code안에 담아진 카카오의 인가코드를 백엔드로 보내주면 된다.

URL안에 search파라미터에 들어있는 'code'를 get하겠다. 라는 뜻 code에 인가코드의 정보가  담겼다. 

 

 

useEffect(() => {
    axios.post(${process.env.REACT_APP_URL}kakaoLogin${code}).then((r) => {
      console.log(r.data); // 토큰과 함께 오는 정보들
      navigate('/loginSuccess'); 
    });
  }, []);

 

 

 

5. 그 토큰을 받아서 로그인을 유지한다. 

로컬스토리지에 저장한 토큰을 필요할 때마다 request에 담아서 보내면된다. 

 

 

 axios
      .get(주소, {
        headers: {
          Authorization: `Bearer ${localStorage.getItem('token')}`,
        },
      })

 

구현이 완료 되면 코드 정리 해서 다시 업로드 할 예정

'React' 카테고리의 다른 글

Error: React Hook useEffect has missing dependencies:...Either include them or remove the dependency array  (0) 2024.08.19
React: [Error] Firebase 사용자 photoURL  (0) 2024.01.19
React: Path Parameters  (0) 2023.12.27
node_modules (npm)과 Yarn Berry  (0) 2023.10.30
OAuth 2.0(생활코딩) 개념  (0) 2023.09.23
'React' 카테고리의 다른 글
  • React: [Error] Firebase 사용자 photoURL
  • React: Path Parameters
  • node_modules (npm)과 Yarn Berry
  • OAuth 2.0(생활코딩) 개념
hyejeong_02
hyejeong_02
  • hyejeong_02
    프론트엔드 개발일지
    hyejeong_02
  • 전체
    오늘
    어제
    • 분류 전체보기 (24)
      • React (9)
      • 네트워크 (2)
      • git (2)
      • HTML (0)
      • CSS (1)
      • Typescript (1)
      • java script (3)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    react-hook-form
    intersectionObserver
    Prettier
    얕은 복사
    var와 let의 차이
    불변성
    의존성배열
    제어 컴포넌트
    redux
    uncontrolled
    무한스크롤
    controlled
    useefftect
    useeffect오류
    리렌더링
    js
    비제어 컴포넌트
    ESLint
    infiniteScroll
    react
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
hyejeong_02
React : Refresh Token &Access Token& Cookie(브라우저 저장소)
상단으로

티스토리툴바