3 분 소요

local에서 구동 : github.io 폴더에서 powershell 열어서 bundle exec jekyll serve

[TIL] JWT / API

JWT

인증 및 인가

먼저, JWT를 알아보기 전에 Authorization(인가)과 Authentication(인증)의 차이를 알아야 한다.

  • Authentication(인증): 로그인! 내가 이 사이트에 가입된 회원임을 아이디와 비밀번호를 이용해서 사용할 수 있는 사람인지를 체크하는 것! 그것이 인증

  • Authorization(인가): 사용자가 로그인으로 인증을 하고 난 후 허용된 사람만 사용할 수 있는 기능을 사용할 수 있을지 없을지에 대한 인가!

JWT와 Session

JWT는 인가와 관련된 기술.

어떤 사용자가 특정 웹 사이트에서 활동을 하고 있을 때마다 사이트는 그 사용자에게 허용을 해줄지 말지에 대해 결정해서 응답해주어야 한다.

보통 session(세션) 방식을 많이 사용해왔다고 한다. 로그인된 사용자는 “세션”을 받게 되고, 그 일부를 사용자에게 전달하여 Session ID라는 이름의 쿠키로 저장하고, 일부를 서버의 메모리나 데이터베이스에 저장한다.

그래서 이 사이트에서 요청을 보낼 때마다 이 세션 ID를 실어서 보낸다. 그러고 활동을 할 때마다 서버에서 맞는 짝을 확인하여 있으면 활동 허용을 해주는 식으로 동작한다.

근데 이제, 이거는 에러 때문에 서버가 엎어지게 되면 사용자들의 로그인이 다 튕기게 되고, 하드나 데이터베이스에 저장해서 넣었다 뺐다 하는 것도 비효율적이다.

그리하여 이 부담을 줄이기 위한 방식이 JWT이다.

출처:https://www.youtube.com/watch?v=1QiOXWEbqYQ [얄코님 유튜브]

JWT

jwt는 JSON Web Token의 약자로 Json 포맷을 이용하여 사용자에 대한 속성을 저장하는 Claim 기반의 Web Token이다. JWT는 토큰 자체를 정보로 사용하는 Self-Contained 방식으로 정보를 안전하게 전달한다. 주로 회원 인증이나 정보 전달에 사용된다.

어플리케이션이 실행될 때, JWT를 static 변수와 로컬 스토리지에 저장하게 된다. static 변수에 저장되는 이유는 HTTP 통신을 할 때마다 JWT를 HTTP 헤더에 담아서 보내야 하는데, 이를 로컬 스터리지에서 계속 불러오면 오버헤드가 발생한기 때문이다.클라이언트에서 JWT를 포함해 요청을 보내면 서버는 허가된 JWT인지를 검사한다. 또한 로그아웃을 할 경우 로컬 스토리지에 저장된 JWT 데이터를 제거한다.

JWT는 Header, Payload, Signature의 3 부분으로 이루어지며, Json 형태인 각 부분은 Base64로 인코딩 되어 표현된다. 또한 각각의 부분을 이어 주기 위해 . 구분자를 사용하여 구분한다. 추가로 Base64는 암호화된 문자열이 아니고, 같은 문자열에 대해 항상 같은 인코딩 문자열을 반환한다.

  1. Header(헤더) 토큰의 헤더는 typ과 alg 두 가지 정보로 구성된다. alg는 헤더(Header)를 암호화 하는 것이 아니고, Signature를 해싱하기 위한 알고리즘을 지정하는 것이다.

  2. PayLoad(페이로드) 토큰의 페이로드에는 토큰에서 사용할 정보의 조각들인 클레임(Claim)이 담겨있다. 여기에 정보들을 넣을 수 있다.

  3. Signature(서명) 서명(Signature)은 토큰을 인코딩하거나 유효성 검증을 할 때 사용하는 고유한 암호화 코드이다. 서명(Signature)은 위에서 만든 헤더(Header)와 페이로드(Payload)의 값을 각각 BASE64로 인코딩하고, 인코딩한 값을 비밀 키를 이용해 헤더(Header)에서 정의한 알고리즘으로 해싱을 하고, 이 값을 다시 BASE64로 인코딩하여 생성한다.

출처: https://mangkyu.tistory.com/56 [MangKyu’s Diary]

그리고 JWT를 사용하는 것은 만능이 아니라고 한다. 로그인을 세션으로 구현하면 각자 컴퓨터에서 접속한 유저들을 서버에서 알 수 있으나 JWT는 그것을 알 수 없기 때문에 다른 기기에서 로그인할 때 기존에 로그인되어 있던 기기가 알 수 없는 현상이 있다고 한다. 또한, Stateless하기 때문에 한번 만들어지면 제어가 불가능하다. 즉, 토큰을 임의로 삭제하는 것이 불가능하므로 토큰 만료 시간을 꼭 넣어주어야 한다.


API

API란?

기본적으로 어떤 기기를 만들 때 사용자와 소통하기 위한 Interface가 있어야 한다.

ex) TV를 볼 때의 리모컨, 브라우저에서는 버튼이나 스크롤 등등

그런데! 당연히 소프트웨어와 소프트웨어 사이에도 interface라는 게 있을 것이다. 왜냐하면 그 사이에서도 정보를 주고 받아야 하니!! 그럼 소통 창구가 있어야 할 것이다. 그렇다고 아무렇게나 내가 요청하고 싶은대로 정보를 요청하거나 주면 서로 소통을 어떻게 할까?

그러니 형식/매뉴얼이란 것이 필요해진다. 그래서 이처럼 소프트웨어 간에 지정된 형식으로 요청, 명령을 받을 수 있는 수단을 API (Application Programming Interface)라고 한다.

그 중 Rest API 가 뭔지도 알아보자.

일단 오늘날 흔하게 사용되는 형식은 Rest api는 요청 자체로도 어떤 정보인지 추론이 쉽다는 장점이 있다.

사이트 도메인의 끝에 /food 등을 붙이면 어떤 요청(food 면 음식들의 리스트라든지)인지 알 수 있다.

쨌든 저 /어떤것 이 구분자를 URI라고 한다!

근데 이제, 무슨 정보를 가져오기만 하는 건 아닐 것 아닌가? 정보를 추가하거나 삭제하거나 업데이트하거나 할 수도 있다. 이것이 바로 CRUD (Create, Read, Update, Delete)

Rest API로 요청을 보낼 때는 HTTP라는 규약을 사용해서 요청하는 데 CRUD 말고도 다양한 메서드들이 있다.

사실 메서드들이 create은 무조건 create / post는 무조건 post로만 사용할 수 있는 것은 아니다. 그래서 보통 Rest API의 URI는 동사가 아닌 명사들로 이루어지도록 한다는 것이 규칙! (맨 뒤에 메서드 POST, DELETE 등이 붙으면 그 메서드로 실행하기 때문에..)

그래서 소프트웨어 개발 중 HTTP로 통신을 할 때 이런 규약들을 잘 지키면서 Restful한 서비스를 만들면 좋겠다는 것이다.

출처: https://mangkyu.tistory.com/56 [MangKyu’s Diary]

댓글남기기