Spring-React : 카카오 소셜 로그인 + JWT (3) JWT를 사용하기 전에 알아야 할 것들

우진·2022년 4월 28일
0
post-thumbnail

(3) JWT를 사용하기 전에 알아야 할 것들


서론.

해당 프로젝트에서는 오로지 카카오 소셜 로그인 만 사용한다. ( ID/PW 사용안함! )

이전 포스팅✅에서는 엑세스 토큰을 이용해 카카오 서버에서 사용자 정보를 받아오고 그것을 DB에 저장하는 법까지 알아보았다. 이어서 JWT를 발급해 프론트 측에 넘기기 전에, 필요한 지식들에 대해 알아보려고 한다.


사용한 의존성 🍃

기본 의존성 :
Spring Web
Spring boot DevTools
Lombok
Spring Security
MySQL Driver
spring Data JPA


추가한 의존성 :
jackson-databind
jackson-datatype-jsr310
java-jwt



1. JWT(Json Wed Token) 란?


JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. JWTs can be signed using a secret (with the HMAC algorithm) or a public/private key pair using RSA or ECDSA.(공식 홈페이지)



요약하자면, JWT는 Json 형식으로 되어있고, 디지털 서명이 되어 있다는 것이다. 그리고 서명 방식에는 HMAC , RSA 등 여러 가지가 있다고 한다. 나는 위 방식 중에 HMAC 을 사용할 예정이다.


2. JWT(Json Wed Token)의 구조


JWT 는 Header Payload Signature 각 세 부분으로 나뉜다. 아래 이미지를 살펴보자.



JWT 가 최종적으로 띄는 형태는 왼쪽의 Encoded 부분이다. 위에서 말한 세 부분은 각각 base64 라는 통상적인 방식으로 인코딩된다. 또한 세 부분을 나누는 구분점 .이 있다.

  1. Header : Signature 를 암호화한 알고리즘에 대한 정보, 해당 토큰의 타입 정보가 들어간다.

  2. Payload : Claim 을 포함하는 부분이다. 클레임에는 등록된 클레임개인 클레임이 있다.

    • 등록된 클레임 : iss (발행자), exp (만료 시간), sub (제목), aud (청중) 등이 있지만 필수 요소는 아니다.
    • 개인 클레임 : 당사자 간에 정보를 공유하기 위해 생성된 맞춤 클레임이다. 우리는 이 개인 클레임에 사용자를 식별할 수 있는 id 값을 넣을 것이다.
      단, 해당 클레임에서 민감한 정보는 다루지 말아야한다. 앞서 말한 base64 방식은 복호화가 가능하기 때문에 누구에게나 노출될 수 있다.

  3. Signature : 서명을 하는 방식은 간단하다. 앞서 만든 Header Payload(각각 base64 로 인코딩 된 상태) 에 자신의 Secret Key를 더해 Header에서 언급했던 방식으로 해싱을 한다. 그리고 그 값을 또 다시 base64 로 인코딩하면 된다.
    당연한 얘기지만 Secret Key는 어디에도 노출되면 안된다.😅 토큰의 유효성을 체크할 핵심 키이기 때문에 조심히 다뤄야 한다.


JWT는 사용자의 민감한 정보들을 전달하는 것 보다는 서명된 토큰 자체에 중점을 둔다. 토큰에 서명을 한 사람이 맞다면 가지고 있던 비밀 키로 복호화 할 수 있을 것이고, 그렇지 않다면 그건 위조되었거나 유효하지 않은 토큰이므로 서버로의 접근을 제한할 수 있다.


3. Security Filter 란?

JWT 를 설명하다가 갑자기 Security Filter 로 이야기가 튀어서 당황스러울 수 있다. 하지만 이 Filter 에 대한 이해가 전혀 없다면, 토큰을 무사히 발행해도 유효성 체크를 하기가 어려울 수 있다.

나는 이미 시행착오를 겪어보았기 때문에😭😭 여기서 간단히 짚고 넘어가는 것을 추천한다.

기본적으로 DispatcherServlet(FrontController)이 요청을 받기 이전에 Filter 를 거쳐가게 되어 있다. 즉, api를 작성한 Controller 의 로직이 실행되기 이전에 필터가 동작하는 것이다. 그 중에서도 Security Filter가 가장 우선적으로 실행된다.
Security Filter의 구성과 동작 순서는 아래 이미지와 같다.

이 중에 꼭 알아둬야할 필터는 UsernamePasswordAuthenticationFilter 이다.
Security Config 에 .formlogin()설정을 해본 적이 있을 것이다. 이 필터는 폼 로그인을 할 때 username password 를 이용해 인증을 진행해주는 필터이다.

이 필터에서 UserDetails UserDetailsService 가 사용된다. 정상적으로 인증이 완료되면 Authentication 에 회원 정보를 담은 채로 시큐리티 세션을 생성한다.
아마 컨트롤러에서 이때 생성된 세션을 불러와 회원 정보를 얻어 본 적이 있을것이다.(Principal 객체)



도움 받은 영상 :
https://www.youtube.com/c/%EB%A9%94%ED%83%80%EC%BD%94%EB%94%A9


마치며.

하지만 이 프로젝트에서는 폼 로그인을 사용하지 않을 뿐더러 JWT 로 사용자 인증을 할 것이기 때문에 위의 필터가 사용되지 않는다. 그러므로 Authentication 이 만들어 지지 않는다.
이러한 문제로인해 인증된 사용자의 정보를 불러올 다른 방법을 강구해야한다. 이는 이후의 포스팅에서 다룰 예정이다. 많관부많관부~🥳💖

profile
백 개발을 시작한 응애개발자

0개의 댓글