항해99 1주차 WIL - JWT 란? API 란?

Ming-Gry·2022년 9월 25일
1

항해99 WIL

목록 보기
1/12

1) JWT 란?

1-1) JWT 가 뭐야?

사진 출처 : https://jwt.io/

위의 사진 출처인 JWT 공식 사이트(맞나...?) 에는 아래와 같은 문장으로 JWT 를 설명한다.

JWT 는 당사자 간에 정보를 JSON 개체로 안전하게 전송하기 위한 간결하고 독립적인 방법을 정의하는 개방형 표준 (RFC 7519) 입니다. 이 정보는 디지털로 서명되어 있으므로 확인하고 신뢰할 수 있습니다.

출처 : https://jwt.io/introduction

처음 듣는 사람은 이게 대체 뭔 소리인가... 싶을 것이다. 이를 쉽게 풀어보면 당사자 = 클라이언트 & 서버JSON 방식으로 사용자의 정보를 전송하기 위한 인터넷 표준 정도라고 이해하면 될 것 같다.

1-2) JWT 의 특징은?

가장 큰 특징은 Stateless 하다는 것이다. 아주 간단히 말해서 서버에서 클라이언트의 정보를 저장하고 있지 않다. 반대로 서버에서 클라이언트의 정보를 저장하고 있으면 Stateful 하다고 할 수 있다. Stateless 의 반대 격인 Stateful 한 방식은 Session 방식이며, JWT 와 Session 의 차이'Stateless 이냐 Stateful 이냐의 차이' 로 말할 수 있다.

Stateless 와 Stateful 에 대한 개념은 조금 더 깊이 들어가면 범위가 조금 확장되긴 하지만 초보자의 수준에서는 서버에서 클라이언트의 정보를 저장하고 있느냐 아니냐의 차이로 이해해도 무방하다고 생각한다. 그래도 궁금한 사람을 위해 아래의 url 을 남겨놓는다.

그리고 JWT 와 Session 의 차이는 코린이의 인기스타 니꼬쌤과 다른 블로그의 글이 너무 잘 정리되어 있어 추가한다.

Stateful vs Stateless : https://5equal0.tistory.com/entry/StatefulStateless-Stateful-vs-Stateless-%EC%84%9C%EB%B9%84%EC%8A%A4%EC%99%80-HTTP-%EB%B0%8F-REST

Session vs Token vs Cookie - 니꼬쌤 : https://www.youtube.com/watch?v=tosLBcAX1vk
Cookie & Session vs JWT - 블로그 : https://tecoble.techcourse.co.kr/post/2021-05-22-cookie-session-jwt/

1-3) JWT 의 구조

이 정도면 JWT 가 어떤 것인지 어디서, 왜 사용하는지 Session 과의 차이는 어떤 것인지 감이 조금 왔을 것이다. 이제 JWT 공식 사이트를 함께 보며 JWT 가 도대체 어떻게 생겨먹은 녀석인지 머리 / 가슴 / 배(?) 근데 진짜 머리 가슴 배 같긴 해... 진짜야...분해해보며 확인해보자.

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

포토샵 하느라 좀 귀찮긴 했는데 그래도 만들어봤다. 공식 사이트에 들어가자 마자 스크롤을 조금 아래로 내리면 이런 화면이 나온다. 이것만 알면 JWT 가 어떻게 생겨먹은 녀석인지 머리 / 가슴 / 배로 조질 수 알 수 있다.

JWT 는 헤더, 페이로드, 시그니처로 나뉘며, 왼쪽 빨간색 글씨가 헤더, 왼쪽 보라색 글씨가 페이로드, 왼쪽 하늘색 글씨가 시그니처로 인코딩 된다. 반대로 인코딩된 JWT 를 디코딩하면 오른쪽의 헤더, 페이로드, 시그니처를 확인할 수 있다.

머리 / 가슴 / 배를 확실히 조지기 분해해보기 전에 1-1) 에서 설명한 개념을 다시 한 번 확인해보자.

JWT 는 당사자 간에 정보를 JSON 개체로 안전하게 전송하기 위한 간결하고 독립적인 방법을 정의하는 개방형 표준 (RFC 7519) 입니다. 이 정보는 디지털로 서명되어 있으므로 확인하고 신뢰할 수 있습니다.

출처 : https://jwt.io/introduction

아까는 미처 보지 못했던 디지털로 서명되어 있다는 말이 나온다! 사진에 보면 JWT에 사용할 알고리즘에 HS256 이 선택되어 있다. 쉽게 말해 JWT는 다른 사람이 위조하지 못하게 HS256 이라는 암호화 알고리즘에 의해 시그니처 부분이 암호화 되어 있다. 다시 말해 우리가 현실의 세계에서 나를 인증하기 위해 사인을 하듯이! JWT에도 나 임을 인증하기 위해 암호화 알고리즘으로 사인을 남기는 것이다!! 이에 대한 정확한 설명은 아래에서 추가로 하도록 하겠다.

사진 출처 : https://ko.wikipedia.org/wiki/%ED%8C%8C%EC%9D%BC:%EA%B9%80%EC%9A%A9%ED%83%9D_%EC%8B%9C%EC%9D%B8_%EC%82%AC%EC%9D%B8.JPG

헤더

헤더는 그 하위에 alg - 시그니처에 어떠한 암호화 알고리즘이 쓰였는지(여기서는 HS256이 적용되었다.) 와 typ - JWTBase64 로 인코딩 되어 있다.

Base64암호화 알고리즘은 아니다. 그러므로 누구나 쉽게 Base64 로 인코딩 / 디코딩할 수 있다! 아래의 페이로드 부분에서 더 자세히 다루도록 하고, Base64 관련된 포스팅은 아래에 있으니 들어가서 확인해보도록 하자.

Base64 란 무엇일까? : https://devuna.tistory.com/41

Base64 인코딩이란 무엇일까? : https://wookkl.tistory.com/22

페이로드

페이로드클레임이라 불리우는 토큰의 정보들이 담겨져 있는 곳이다. iss(발급자), exp(만료시간), sub(주제), aud(대상) 등이 들어가며 기타 RFC7519 기준에 부합하는 클레임을 넣을 수 있다. 또한 IANA JSON 웹 토큰 레지스트리에 정의된 것처럼 원하는 정보를 넣을 수도 있다. 여기에는 해당하지 않지만, 클라이언트와의 합의 하에 원하는 정보를 넣을 수도 있다!

어쨌든 페이로드에는 토큰의 정보가 담긴다는 점이며, 서버와 클라이언트에서 필요한 정보들을 커스텀해서 넣을 수도 있다는 점이다!

실제로 필자의 프로젝트에서도 오른쪽과 같이 sub 에는 email, auth 에 권한, memberId 에 서버에서 관리하고 있는 member 번호, exp 에는 유효기간을 정의하여 사용했다. 여기서 memberId 는 클라이언트에서 JWT 를 파싱하여 로그인한 유저의 정보를 알기 위해 넣은 개인 클레임이라고 할 수 있겠다.

JWT 의 헤더와 페이로드에서 가장 중요한 부분은 이 곳이다. 페이로드는 헤더와 마찬가지로 Base64 로 인코딩되어 있다. 그러므로 JWT 가 어떤 방법으로든 유출되면 유출된 JWT 는 Base64로 아주 손쉽게 디코딩할 수 있다. 아주 친절하게도 JWT 공식 사이트에 JWT 를 넣어도 디코딩할 수 있다!

그러므로 공식 사이트에서도 밝혔듯이 JWT 페이로드와 헤더에는 !절대! 유저의 이름이나 생년월일 등과 같이 민감할 수 있는 정보와 비밀 번호 등 비밀 정보를 입력해서는 안 된다.

시그니처

공식 사이트에서 언급하듯, 시그니처 부분은 Base64로 인코딩된 헤더와 페이로드, 그리고 서버에서 지정한 비밀키를 암호화 알고리즘으로 암호화하는 것을 말한다. 보통 SHA256, SHA512와 같이 단방향 암호화 방식을 사용해 암호화는 가능하지만 복호화는 불가능하도록 만든다.

시그니처 부분에 인코딩된 헤더, 페이로드, 비밀키를 함께 넣는 이유는 Salting 때문이지 않을까 싶다. 정확하진 않고 나의 추측이다...ㅎ...... Salting 은 암호화 방식의 하나로, 레인보우 테이블과 브루트포스를 방지하도록 하기 위함이다. 이 부분은 본 포스팅에서 다루기 어려울 것 같아 아래의 참조로 남겨두겠다. 언젠가 기회가 되면 포스팅해보자!

[Programming] 암호화 알고리즘 종류와 분류 : https://velog.io/@inyong_pang/Programming-%EC%95%94%ED%98%B8%ED%99%94-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%A2%85%EB%A5%98%EC%99%80-%EB%B6%84%EB%A5%98

패스워드의 암호화와 저장 : https://st-lab.tistory.com/100

2) API 란?

API 란 Application Programming Interface 라는 용어로, 어떤 응용프로그램에서 데이터를 주고 받기 위한 방법을 의미한다. 어떤 특정 사이트에서 특정 데이터를 공유할 경우 어떠한 방식으로 정보를 요청해야 하는지, 그리고 어떠한 데이터를 제공받을 수 있을지에 대한 규격들을 API 라고 한다.

출처 : https://steemit.com/kr/@yahweh87/it-api

그렇기 때문에 사이트에 따라 API 의 규격 및 방식은 모두 제각각이다. Open API, Kakao API, Naver API, Google API 들이 모두 다르다. 뿐만 아니라 우리가 개발한 사이트의 API 도 위의 API 들과 다르다!

사실 좀 어렵게 얘기해서 그렇지 API 는 어떻게 데이터를 주고 받을 것인가에 대한 약속이다. 개발 프로젝트를 진행한다면, 프론트엔드와 백엔드의 약속이라고 할 수 있는 것이다. 그렇기 때문에 기능별로 어떻게 API 를 주고받을 것인지 잘 정의하는 것이 중요하다.

프론트엔드던 백엔드던 이 API 가 잘 지켜지지 않으면 원하는 데이터를 주고받을 수 없을 뿐더러 신나는 에러 파티가 펼쳐질 것이다.

진짜다... CORS 문제를 해결했다면, 대부분의 프론트엔드 및 백엔드 연결 에러는 여기에서 발생한다. 특히나 백엔드 입장에서 PostMan으로 테스트 해봤을 때는 아주 잘되는데 프론트엔드에서는 안된다면 여기에서 타입이나 오타 등의 문제가 발생했을 가능성이 있다.

그리고 API 는 프론트엔드와 백엔드의 약속이기 때문에 API 가 변경되어야 한다면 바꾼 뒤에 일방적으로 통보하지 말고 미리 협의 후에 API 를 다시 정하는 습관을 들이도록 하자.

실제로 필자가 프로젝트에서 사용했던 API 명세서 중 로그인 부분을 가져와봤다. 위에서 보는 것과 같이 API 명세서에 Method, URL, Request, Response, Error Message, 참고 사항 등을 넣어 프론트엔드와 백엔드 모두 API 명세서를 함께 정의한 뒤 이를 보고 개발을 진행했다.

profile
항상 진심이지만 뭔가 안풀리는 개발 (주의! - 코린이가 배우고 이해한 내용을 끄적이는 공간이므로 실제 개념과 일부 다를 수 있음!)

0개의 댓글