대범하게

[React] 로그인 기능(JWT, Local Storage): token 저장, 서버에 전달하기 본문

Development/React

[React] 로그인 기능(JWT, Local Storage): token 저장, 서버에 전달하기

대범하게 2023. 1. 11. 11:16
반응형

유튜브 프리미엄은 로그인을 해야 광고를 보지 않을 수 있고, 쿠팡에서는 로그인을 해야 내 장바구니로 넘어갈 수 있다. 이러한 인가 과정에서 필수적 요소는 바로 token이다. ! 로그인 후 발생되는 token을 localStorage에 저장하고, 특정 사이트에서 필요할 때 서버에 보내는 것까지의 과정을 알아보자.

 

0. token, 왜 필요한가?

HTTP는 단기기억상실과 같은 stateless 특성을 가지고 있기 때문에 한 번 로그인을 한다고 그 사실을 계속 기억하지 못한다. 따라서 원래대로라면 로그인을 했더라도 마이페이지 등 로그인이 필요한 사이트에 접속할 때마다 로그인을 진행해야 한다.

이러한 상황을 막기 위한 것이 token이다 !

먼저 로그인을 완료하면 인증 스티커와 같은 token을 전달받고, 마이페이지 등 로그인이 필요한 사이트를 접속할 때마다 서버에 token을 보내며 로그인을 한 유저인지, 권한이 있는지 알려줌으로써 다시 로그인을 할 필요가 없다.

 

1. JWT란 무엇인가?

JWTJason Web Token의 약자이다.

모바일 앱이나 웹에서 사용자 인증(Authentication)을 수행할 때 사용하는 암호화된 토큰이다.

사용자의 정보 등을 암호화하여 사용자 정보가 필요한 API를 호출할 때, 해당 토큰을 보내주면 백엔드에서 그 토큰을 검증(verity)하는 과정을 거친다. 그 후 response를 해주는 것이다.

 

개발자 도구에서 Local Storage와 Session Storage가 있는 것을 확인할 수 있다.

 

2. Local Storage ? Session Storage?

둘 다 HTML5에 추가된 '저장소'이다.

로컬 스토리지(Local Storage)에 들어간 데이터는 유저가 지우지 않는 이상 브라우저에 계속 남아있게 된다. 

하지만, 세션 스토리지(Session Storage)에 들어간 데이터는 브라우저 탭을 닫을 경우에 사라지게 된다. 

이를 통해 '로그인을 유지'시키기 위해서는 세션 스토리지가 아닌 로컬 스토리지에 token을 넣어주면 된다는걸 알 수 있다. 

// 토큰을 localStorage에 set
localStorage.setItem("key", token);

// 토큰을 localStorage에서 get
localStorage.getItem("key");

*LocalStorage와 SessionStorage의 차이: https://bo5mi.tistory.com/213

 

[기술면접] LocalStorage와 SessionStorage의 차이

LocalStorage와 SessionStorage의 차이 애매한 카테고리 분류로 기술면접에 들어온 로컬 스토리지와 세션 스토리지에 대한 정리를 시작해보자. 프론트든, 백이든 필히 질문가능한 개념이다. 바로 내가

bo5mi.tistory.com

 

3. 로그인 과정

1. 최초 회원가입 시 비밀번호를 DB에 바로 저장하지 않고 Bcrypt를 이용해 암호화를 한 후 비밀번호를 DB에 저장한다. 

  * Bcrypt: 현업에서 많이 사용하고 있는 패스워드 암호화 알고리즘/Bcrypt 모듈을 설치해서 사용가능하다.

 

2. 유저 정보를 저장한 후에 로그인을 할 때 암호화된 비밀번호화 비교하는 검증 과정을 거친 후 일치하게 되면 로그인을 한다.

 

3. 로그인을 할 때 JWT token을 생성하고 token을 localStorage에 저장하여 로그인을 유지시킨다.

 

4. 로그아웃을 할 때엔 localStorage에 있는 토큰을 지운다. 

// 토큰을 localStorage에서 삭제
localStorage.removeItem("key");

 

4. 어떻게 저장하고, 서버에 보내는가?

1. 로그인 성공시 localStorage에 token 저장

1) 백엔드 측에서 설정한 로그인 성공시 response.MESSAGE와

2) 토큰의 발급 유무에 따라 로그인 성공 여부를 알 수 있다.

 

token이 true이면(있으면) localStorage에 login-token이라는 키 값으로 token을 저장한다.

(localStorage에 저장할 경우 해당 도메인에 영구저장된다.)

//아래 부분을 fetch 함수의 두 번째 .then()에 작성

if (response.ACCESS_TOKEN) {
	localStorage.setItem('login-token', response.ACCESS_TOKEN);
}


//참고 : 코드 전문

handleLogin = () => {
    fetch(`${signinAPI}/login`, {
      method: 'POST',
      body: JSON.stringify({
        email: this.state.email,
        password: this.state.password,
      }),
    })
   
      .then(response => response.json())
  
      .then(response => {
        if (response.ACCESS_TOKEN) {
          localStorage.setItem('login-token', response.ACCESS_TOKEN);
        }
      });
  };

 

2. 인가(Authorization)가 필요한 사이트에서 token 전달

이제 마이페이지, 장바구니 등 인가 과정이 필요한 사이트에서 데이터를 요청할 때, 

아래의 방법으로 localStorage에 저장해두었던 token을 꺼내 함께 전달하면 된다.

fetch 함수의 두 번째 인자는 조건 부분이므로, 이 부분을 headers에 아래 부분을 작성한다.

 

- 'Content-Type': 'application/json': 데이터를 json 형태로 전송

- Authorization: localStorage.getItem('login-token'): localStorage에 login-token key로 저장한 값을 HTTP Authorization 요청 헤더로 전달

fetch(`${API}/login`, {
  method: "GET",
  header: {
    "Content-Type": "application/json",
    Authorization: localStorage.getItem("login-token"),
  },
  body: JSON.stringify({}),
  // 생략
});

 

 

Reference

https://www.z00mni.com/posts/%EB%A1%9C%EA%B7%B8%EC%9D%B8%20%EA%B8%B0%EB%8A%A5%20%EA%B5%AC%ED%98%84(jwt,local%20storage) 

https://dev-bomdong.tistory.com/19

Comments