관리 메뉴

개발하는 동그리

[인증/보안] JWT(Json Web Token) 인증 본문

IT 정보/Spring

[인증/보안] JWT(Json Web Token) 인증

개발하는 동그리 2022. 7. 29. 20:58
반응형

JWT 공식 사이트 : https://jwt.io/

 

JWT.IO

JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.

jwt.io

 

JWT 사용하는 이유

  • 로그인 요청을 보낼 때 서버에서 인증하고 권한을 부여 
  • 매번 로그인할 필요없이 세션 정보를 저장했다가 인증이 필요할 때마다 세션정보를 비교하여 인증 상태 유지
  • 서버기반의 인증방식은 매번 인증 요청마다 처리를 해야하기 때문에 부담이 큼
  • 따라서 부담을 줄이기 위해 토큰 인증 방식을 사용

토큰 인증방식과 세션 인증 방식의 차이점

 

JWT란!?

  • 클라이언트가 인증정보를 가지고 있는 것 (암호화 된 상태)
  • 가장 대표적으로 사용하는 토큰 방식

 

JWT의 구성 요소

  • 클라이언트는 (로컬 스토리지, 쿠키, 리액트의 스테이트)등 다양한 공간에 저장
  • aaaaaa.bbbbb.ccccc 
  • a = Header
    • 어떤 종류의 토큰인지 ex.) JWT
    • 어떤 알고리즘으로 암호화 하는가 
    • Json 객체를 base64 방식으로 인코딩
{
  "alg": "HS256",
  "typ": "JWT"
}
  • b = Payload
    • 유저의 정보 등 기타 필요 정보
    • 접근 권한을 부여
    • Signature를 통해 유효성 검증을 하지만, 민감한 정보는 되도록 삼가
    • Json 객체를 base64 방식으로 인코딩
{
  "sub": "someInformation",
  "name": "phillip",
  "iat": 151623391
}
  • c = Signature
    • Header,Payload를 base64 인코딩한 값과 salt값의 조합으로 암호화 된 값.
    • Header에서 지정한 알고리즘을 사용하여 암호화
HMACSHA256(base64UrlEncode(header) + '.' + base64UrlEncode(payload), secret);

 

JWT의 인증 방식

  • 엑세스 토큰(Access Token)
  • 리프레시 토큰(Refresh Token)
    • 엑세스 토큰은 보호된 정보들에 접근 할 수 있는 권한 부여 
    • 실제 클라이언트가 처음 인증을 받게되면, (엑세스, 리프레시 토큰)두 가지를 다 받게된다. 실제 사용하는 토큰은 엑세스 토큰이다. 
    • 엑세스 토큰이 탈취될 경우 위험에 노출되기 때문에 유효기간을 짧게하고, 리프레시 토큰을 이용해 서버에 접근없이 새로운 엑세스 토큰 발급
    • 따라서 사용자 편의보다 안전이 중요하다면 리프레시 토큰을 사용하지 않는곳도 많음.

 

JWT의 인증 절차

  • 클라이언트가 서버에 로그인 요청
  • 아이디/비밀번호 일치 확인 후 클라이언트에게 암호화 된 토큰 생생 (엑세스,리프레시 토큰)
  • 클라이언트는 (Local Storage, Session Storage, Cookie 등)에 저장
  • 다음 요청시 HTTP 헤더(Authorization 헤더)또는 쿠키에 토큰을 담아보낸다. 
    • bearer authentication 이용
  • 서버는 토큰을 해독하여 발급한 토큰과 일치하면, 클라이언트의 요청을 처리하고 응답을 보내준다. 

JWT 장점과 단점

  • Statelessness & Scalability (무상태성 & 확장성)
    • 서버는 클라이언트의 정보를 저장할 필요가 없음
    • 토큰을 헤더에 추가함으로써 인증 절차 완료 
    • 서버를 여러개 가진 서비스라면, 각각의 서버에서 인증할 필요없이 하나의 토큰으로 여러 서버의 인증 가능
  • 안정성
    • 암호화 된 토큰을 사용하고, 암호화 키를 노출할 필요가 없음
  • 어디서나 생성 가능
    • 토큰을 확이하는 서버가 꼭 토큰을 만들지 않아도 됨
    • 토큰 생성용 서버를 만들거나, 다른 회사에서 토큰 관련 작업을 맡기는 것 등 다양한 활용 가능
  • 권한 부여에 용이
    • 토큰의 payload(내용물) 안에 어떤 정보에 접근 가능한지 정의할 수 있음
      • ex.) 사진 권한만 부여 / 연락처 권한만 부여

  • Payload는 해독될 수 있음
    • Payload는 base64로 인코딩 되어있다. 토큰을 탈취하여 해독하면 저장한 데이터가 노출될 수 있으므로, 중요한 정보는 넣지 말 것
  • 토큰의 길이가 길어지면 네트워크 부하
    • 토큰에 저장하는 정보의 양이 많아질수록 토큰의 길이가 길어짐
    • 따라서 요청마다 길이가 긴 토큰을 함께 전송하면 네트워크에 부하가 걸림
  • 토큰은 자동 삭제가 안됨
    • JWT의 장점으로 무상태성이 존재하는데, 상태를 저장하지 않기 때문에 생성된 토큰은 자동으로 삭제되지 않으므로, 반드시 토큰 만료 시간을 추가해야한다. 
    • 탈취된 토큰의 기한이 만료될 때까지 대처가 불가능하므로, 만료시간을 길게 설정하면 안된다. 
  • 토큰은 어딘가 저장되어야 함
    • 클라이언트가 인증이 요구되는 요청을 보낼때마다 함께 보내야 함

 

JWT Bearer 인증

Session & Cookie 인증 방식

  • 사용자가 로그인 요청을 보내면 확인 후 Session ID를 발급
  • 발급한 ID를 이용해 다른 요청과 응답을 처리하는 방식

Token 인증 방식

  • 저장소 필요없이 로그인시 토큰 발급하고 데이터 요청시 토큰을 헤더를 통해 전달하여 응답받는 방식

장점

  • 토큰 기반 인증은 쿠키나 세션보다 보안성이 강하고 효율적인 인증방법이다. 
    • HTTP 방식 통신을 사용하는 경우 정보 유출의 위험성이 크다
    • 세션 인증은 세션ID를 보내므로 쿠키보다 보안성은 높으나, 서버에서 처리해야 하기 때문에 서버의 데이터베이스 공간을 차지하게 된다. 
  • 토큰은 데이터가 인코딩 되어있지만, 누구나 디코딩 할 수 있어 유출될 가능성이 잇다. 그러나 서명 필드가 헤더와 페이로드를 통해 만들어져 데이터 변조 후 재전송을 막을 수 있다. 
  • stateless 서버를 만들 수 있다. 
  • 인증정보를 OAuth로 이용할 수 있다. 
  • 요청 헤더 Authorization 필드의 구조
Authorization: <type> <credentials>

 

Bearer 인증 타입

  • JWT or OAuth에 대한 토큰을 사용한다. 

 

코드 

  • @EnableWebSecurity - 스프링 시큐리티 설정 활성화
  • http.csrf().disable() -  csrf 토큰이 포함되야 위조요청을 방지하게 된다. RestAPI 경우 서버에서 인증정보를 보관하지 않기 때문에 굳이 불필요한 작성이 필요하지 않다.
  • authorizeRequests() - 각 url에 따라 권한 접근 제어 관리 옵션 시작
  • antMatchers - 권한 관리 대상 지정
  • permitAll() - 모든 권한에게 공개 
  • .access("hasRole('ROLE_USER')") - user 권한인 사람에게만 공개
  • anyRequest.authenticated() - 나머지 요청들은 인증된 사람에게만 공개
  • .oauth2Login() - oauth2 로그인 설정의 진입점
  • userInfoEndpoint() - 로그인 성공 이후 사용자 정보 가져올 때 설정 담당

 

반응형

'IT 정보 > Spring' 카테고리의 다른 글

[Spring] build.gradle 설정  (0) 2022.08.18
[인증\보안] Spring Security 기본 (인증/ 인가)  (3) 2022.08.02
[JPA] 이론 정리  (3) 2022.07.29
[인증/보안] OAuth2  (2) 2022.07.29
[인증/보안] CORS란!?  (5) 2022.07.28