WIL: 항해 첫 번째 주를 마치며

김하연·2022년 5월 15일
0

TIL: Today I Leaned

목록 보기
6/26

항해 첫번째 주, 첫 프로젝트를 진행하면서 공부하고 실제로 사용했던 JWTAPI의 개념에 대해 정리했다. 이런 이론이나 용어들에 대한 개념이 항상 애매해서 사용하면서도 헷갈렸는데, 이렇게 정리를 통해 좀 더 개념을 잡는 기회가 된 것 같다.


JWT(JSON Web Token)?

우선, JWT를 이해하기 위해서는 쿠키, 세션, 토큰 등 비슷 한 듯 애매하고 헷갈리는 용어들에 대한 이해가 먼저 필요한 것 같아 정리했다.


# 쿠키(Cookies)

서버는 나의 정보를 기억하기 위해 브라우저에 데이터를 저장할 수 있고, 내가 웹사이트에 방문하면 브라우저는 서버에 요청(request)을 보내고 서버는 응답(response)하는 과정을 거친다.
서버의 응답에는 모든 데이터와 내가 찾던 페이지 정보가 있고 그 중에는 브라우저에 저장하고자 하는 쿠키도 포함된다.
브라우저에 쿠키를 저장하면 해당 웹사이트에 방문할때마다 브라우저는 해당 쿠키를 요청과 함께 서버로 보내게 되는데, 이 때 쿠키는 도메인에 따라 제한이 된다. 예를 들어 유튜브가 준 쿠키는 유튜브에만 보내지는 방식이다. 서버가 정한 기간에 따라 유효기간도 있다.
또한 쿠키는 인증 뿐 아니라 여러가지 정보 저장이 가능한데 예를들면 웹사이트의 언어를 설정하는 정보를 저장할 수 있어서, 특정 웹사이트 언어를 영어로 설정해둘 경우 나중에 다시 그 사이트에 접속할 때 영문으로 설정된 웹사이트로 바로 접속할 수가 있게 된다.


# 세션(Session)

http 프로토콜은 stateless(<->stateful(세션))
서버로 가는 모든 요청(reuqest)은 이전의 요청(request)과 독립적으로 다뤄진다. 요청끼리 연결이 없고 메모리가 없다고 보면 된다.
한 번 요청이 끝나면 서버는 내가 누군지 잊어버리기 때문에 요청할때마다 우리가 누군지 다시 서버에 알려줘야 하는데, 이를 하는 방법 중 하나가 세션이다.
예를 들어 'Kim'이라는 유저가 웹사이트에 로그인을 하고싶으면 아이디와 비밀번호를 서버에 보낸다.
서버는 요청받은 이 정보가 맞으면 Session DB에 'Kim'이라는 유저를 생성한다.
해당 세션엔 별도의 id가 있고, 해당 Session id는 Session DB에서 브라우저로 들어오고 저장된다.
유저가 해당 웹사이트에서 다른 페이지로 이동할 경우 브라우저는 Session id를 담은 쿠키를 서버에 보내고, 서버는 쿠키에서 Session id를 확인한다. 이 때 까지도 서버는 아직도 우리가 누군지 모르고 Session id가 담긴 쿠키가 지닌 요청이 있다는 것만 알고 있다.
후에 서버는 요청받은 Session id를 가지고 Session DB를 확인한 후에야 해당 id가 'kim'이라는걸 알고 우리가 누군지 알게되는 것이다.
해당 요청이 끝나고 유저가 또 다른 페이지로 넘어가면 이 모든 프로세스가 반복된다.

  • 쿠키는 그냥 Session id를 옮기는 시스템이자 매개체일 뿐이다.

  • 중요한 유저 정보는 모두 서버에 있다. 유저가 갖고 있는 것은 Session id일 뿐.

  • 세션을 이용해 IOS, Android를 만들 수 있지만 쿠키는 브라우저에만 있기 때문에 사용할 수 없다. 이 경우, Token을 사용한다. 쿠키 대신 서버에 Token을 보내는 것.


# 토큰(Tokens)

토큰은 서버가 기억하는 이상하게 생긴(?) 텍스트이다. ID카드처럼 서버에게 보여줘야 하는 것이라고 이해하면 된다.
서버에 토큰을 보내면 서버는 Session DB에서 해당 토큰과 일치하는 유저를 찾는다.
여기서 세션의 특징은, 현재 로그인한 유저들의 모든 Session id를 DB에 저장해야 한다. 요청이 들어올때마다 서버는 쿠키를 받아서 Session id를 보고 해당 유저를 찾아 다음 작업을 수행하는 것이다. 즉, 요청이 있을 때마다 DB를 찾아야 된다는 뜻으로, 유저가 늘어남에 따라 많은 DB리소스가 필요해진다. 그래서 등장한 것이 JWT


# JWT의 등장

JWT는 정보를 갖고 있는 토큰으로, DB없이 검증이 가능하다.
JWT로 유저 인증을 처리하면 Session DB를 가질 필요가 없고 서버가 유저를 인증하기 위해 많은 일을 하지 않아도 된다.
JWT 방식의 경우에도 우선 사용자 'kim'이 로그인을 하기 위해서는 아이디와 비밀번호를 서버에 보낸다. 이 때 세션과 다른점이 있는데, 유저 아이디와 비밀번호가 일치할 경우 서버는 DB에 뭔가를 생성하지 않고 바로 유저의 id를 가져다가 사인 알고리즘을 이용해 사인을 한다. 그리곤 사인된 정보를 아주 긴 문자열, 'string'형태로 다시 보낸다. 이것이 유저를 인증하는데 필요한 정보를 토큰에 저장한 것이고, 그 토큰을 다시 사용자에게 준다. 동일하게 로그인을 했는데 DB를 건드리는 대신 정보를 사인하고 보내는 것이 다른 점이다.
이제 사용자가 해당 웹페이지의 다른 페이지로 이동할 경우, 브라우저는 서버에 새로 request를 보내 사인된 토큰을 서버에 보내고 서버는 그 토큰을 받아 해당 사인이 유효한지 체크하고 유효하다면 서버는 해당 사용자를 유저로 인증해준다.
서버는 해당 토큰이 유효한지만 검증하면 되고, 세션처럼 DB를 거칠 필요가 없는 것이다.


# JWT 구조

JWT에는 암호화된 세가지 데이터가 담겨있으며 구조는 아래와 같다.

jhbGci1i.tZSI6Ikp.fwpMeJf36
{Header}.{Payload}.{Signature}
  • Header
    어떤 타입의 데이터를 다룰지(JWT 고정), HS256등 어떤 암호화, 해싱 알고리즘을 사용할지에 대한 정보

  • Payload
    실제 보관할 데이터

  • Signature
    유저는 데이터를 볼 수만 있고 서버에서만 수정하는걸 가능하게 하는 부분. signature관리는 전적으로 서버에서만 한다. Header와 Payload, 그리고 '서버에 감춰놓은 비밀 값(비밀키)'를 암호화 알고리즘에 넣고 돌려 나온다.

서버에서는 Header와 Payload를 조합하고 비밀키를 이용해서 해시값을 만들어내는데, 이게 바로 Signature가 된다. Signature값과 계산값이 일치하고, 유효기간도 지나지 않았다면 해당 사용자는 로그인된 회원으로서 인가를 받는다.

인증(Authentication): 로그인, 특정 서비스에 일정 권한이 주어진 사용자임을 인증하는 것.
인가(Authorization): 인증을 받은 사용자가 이후 서비스 여러 기능을 사용할 때 로그인 되어있음을 알아보고 허가해주는 것. 로그인이 유지되는 상태에서 일어나는 일.
JWT = 인가에 대한 것.


Payload	{
  'name: 'Gram Gram'
  'age: '2010',
  'size': 15,
  'money': 1500
}

유저가 임의로 값을 수정하여 money의 값을 15000으로 바꿔서 보내면, 서버에서 데이터를 받고 JWT가 임의로 조작되었는지 확인하는 과정을 거친다.
서버에서는 유저가 보낸 Header와 Payload, 비밀키를 이용해서 직접 Signature를 만들고 유저가 기존에 보낸 Signature값과 비교해 값이 다르면 조작된 데이터라는 것을 알게된다.
이렇기 대문에 비밀키는 이름에 걸맞게 서버에서만 알고 있어야 하고 클라이언트는 알아서는 안된다.


# 세션 vs JWT 장단점

세션을 사용하면 서버는 로그인된 유저의 모든 정보를 저장한다. 해당 정보를 이용하면 새로운 기능들 추가가 가능한데, 예를들어 특정 유저를 삭제하고 싶으면 해당 세션을 삭제하는 방법을 쓰는 것이다.
ex) 인스타그램에서 원하는 디바이스를 강제 로그아웃 시키는 기능
ex) 넷플릭스에서 계정 공유 숫자를 제한하고 몇 명이 로그인하여 시청하는지 알 수 있는 기능들
이 기능들은 세션 DB가 있기 때문에 서버가 누가 로그인 했는지를 모두 저장하고 있어서 가능한 것이다. 이를 위해선 DB를 사고 유지해야하고, 유저가 늘어날수록 DB도 커져야한다는 점이 있다.

JWT를 사용하면 생성된 토큰을 추적하지 않는다. 서버가 아는것은 토큰이 유효한지 여부일 뿐이다.
데이터를 사인하고 유저에게 보내 해당 데이터를 돌려받을 때 유효성을 검사할 수 있다. DB없이 모든 것이 가능하다.
DB를 따로 살 필요가 없지만, 토큰이 만료되기 전까지는 유효한 것이기 때문에 강제 로그아웃과 같은 기능은 불가능하다.
한국 코로나 QR체크 하는 기능이 JWT가 적용된 사례라고 볼 수 있다.




API(Application Programming Interface)?

API를 접할 때 나온 비유가 창구, 메뉴판, 키보드.
간단한 설명으로는 서버와 사용자가 데이터를 주고받기 위한 방법(=코드) / 프로램들이 서로 소통하는 방법 / 코드들끼리 서로 소통하기 위해 만들어진 것 / 애플리케이션에서 데이터를 읽거나 쓰기 위해 사용하는 인터페이스 등이 있었다.

이렇게만 봐서는 이해가 잘 안돼서 구체적인 예시를 찾아보았다.

# 예시 1

우리동네 날씨 정보 보여주는 앱을 만들려면, 가장 중요한건 날씨 정보가 있어야 한다.
이 날씨 정보는 기상청에 있고 기상청에 날씨 정보를 요청해서 응답을 받은 후 화면에서 보여줘야 한다. 이 때 날씨 정보를 가져올 수 있도록 기상청에서 제공하는 접점을 API라고 한다.

제공되는 API 모양 : http://api.dat.go.kr/weather/list
응답받은 데이터: { 'today': 2022-05-15, 'weather': 맑음 }

# 예시 2

배달앱을 예시로 한다면,
백엔드 팀에서는 가게목록API, 메뉴목록 웹 전용API, 메뉴목록 모바일 전용API, 주문API 등을 만들면 프론트엔드 개발팀에서는 이런 API를 사용하여 사용자에게 보여줄 UI를 개발한다.
사용자는 UI를 통해 소통하고 애플리케이션은 API를 사용하여 소통하는 것이다.

		이 url로 get 요청하면
app.get('/detail/:id', function(req, res) { // 이 부분이 API
	db.collection~~~~
    이 코드를 실행해주세요.
}

# API 종류

  • Private API
    회사 자체 서비스를 만들기 위해 사내ㅑ에서 개발하고 사용하는 API
    제 3자에게 공개되지 않음

  • Public API
    기상청 API와 같이 누구나 사용할 수 있4도록 개발해놓은 API


# 드림코딩에서 추천한 Open API 리스트

제일 추천: https://github.com/public-apis/public...
다음 추천: https://public-apis.xyz/page/1
기타언급된 링크들:
https://developers.giphy.com/
https://developer.spotify.com/
https://developer.edamam.com/
http://apimeme.com/?ref=apilist.fun
https://www.kiwoom.com/h/main
https://developers.kakao.com/
https://www.data.go.kr/tcs/dss/selectDataSetList.do




항해 첫 번째 주를 마치며

항해 첫 번째 주는 우선 시작하자 마자 팀 프로젝트를 진행하느라 사실 정신이 없었다.
서버, 클라이언트, DB, Flask, JWT, API 등등.. 처음 듣는 용어와 개념들이 등장했는데 일단 프로젝트는 진행해야 하니 일단은 배운거에서 응용해보고 만들기에 급급해서 내가 사용하는 기술이나 언어들에 대한 이해가 부족했던 것 같다.
WIT 작성을 통해 먼저 API와 JWT에 대해 정리를 해보니 내가 프로젝트에 작업을 진행하면서 사용하고 적용했던 기술이나 구조들이 조금 정리가 된 것 같다.

사실 이 WIT를 작성하기 전에 나는 API가 Open API만을 지칭하는 용어로 알고있었다. 누군가가 만든 데이터베이스를 내가 갖다 쓸 수 있는것들을 API라고 생각했는데, 틀린것만은 아니겠지만 그것보다는 좀 더 넓은 범위로 사용되는게 맞는 것 같다.
Public API뿐만 아니라 Private API까지 포함해서 서버와 사용자가 데이터를 주고받을 수 있도록 연결해주는 방법, 즉 연결해주는 코드를 API라고 보면 될 것 같다.

JWT도 그냥 인증하는 방식 중 하나라고만 생각했는데, JWT이해를 위해 세션과 토큰, 그리고 쿠키라는 개념에 대해 함께 공부해보니 좀 더 명확하게 이해를 할 수 있게 된 것 같다. 세션이나 쿠키, 토큰 같은 단어들이 다 비슷한 것 같으면서도 정확한 의미는 몰랐는데 이번 기회에 정리할 수 있어서 좋았고 덕분에 JWT에 대해 좀 더 자세히 이해할 수 있게 됐다.

돌아오는 두번째 주는 우선 지난주 금요일부터 진행한 알고리즘 주차가 이어진다.
알고리즘 주차에서는 하루 일정이 거의 문제를 풀고 해설하기로 이루어지는데, 문제 풀다가 지루하고 집중력 떨어지는 시간이 온다면.. 또 헷갈리는 다른 용어들에 대한 공부도 진행하면 좋을 것 같다.

짧은 듯 하면서도 길게 느껴졌던 지난 한 주 큰 멘붕 없이 보낸 것 만으로도 다행이다. 아침에 눈 뜨고 밤에 졸려서 지쳐 잠들때까지 코드만 본 것 같고 그만큼 체력도 떨어진 것 같아서 걱정은 되는데.. 99일 무사히 마치려면 컨디션 조절도 잘 해야할 것 같다.

다음주도 화이팅!!!!!!!!!!!!

0개의 댓글