인증 (Authentication)
로그인
서비스의 사용자임을 아이디, 패스워드 등을 통해서 인증받는다.
인가 (Authorization)
인증받은 사용자가 서비스의 기능을 사용할 때 허가해주는 것
로그인이 유지되는 상태에서 일어나는 일
사용자가 서버에 로그인 되어있음이 지속되는 상태
Session의 단점을 해결하기 위해 나온 '토큰 방식'
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
{ "alg": "HS256", "typ": "JWT" }
alg
Verify Siganature 값을 만드는데 사용되는 알고리즘
한쪽 방향으로만 계산이 가능하다. -> 서버의 비밀 값을 알 수가 없다.
typ
토큰의 타입, 항상 "JWT" 이다.
- base64로 디코딩하면 아래와 같이 json 형식의 데이터가 들어있다.
- base64는 너무 보안에 취약하지 않나? -> 그래서 Header와 Verify Signature가 있다.
{ "sub": "1234567890", "name": "John Doe", "iat": 1516239022 }
- Claim: 토큰에 담긴 사용자 정보 등의 데이터
- 누가 누구에게 발급했는지,
- 토큰의 유효 기간
- 서비스가 사용자에게 이 토큰을 통해 공개하기 원하는 내용 (닉네임, 관리자 여부 등)
이후 요청마다 사용자로부터 서버에 보내진다.
서버가 요청마다 데이터베이스에서 찾을 필요가 없다.
- Header, Payload, 서버의 비밀 키 3개를 Header의 암호화 알고리즘에 넣으면 나온다.
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), your-256-bit-secret )
- 서버에 요청이 들어오면 Header, Payload 값을 서버의 비밀 키와 함께 돌려봐서 계산된 결과값이 Verify Signature 값과 일치하는지 확인한다.
session과 같이 모든 사용자의 상태를 기억하고 있다면 기억하는 대상의 상태들을 언제든 제어할 수 있다.
발급한 토큰을 다시 뺐어오거나, 탈취당한 토큰을 무효화하는 방법은 없다. 따라서 실서비스 중에 jwt 만으로 인가를 구현하는 곳은 많지 않다.
만료시간을 가깝게 잡아서 토큰의 수명을 짧게 한다.
수명이 몇 시간이나 몇 분 이하로 짧은 access 토큰과, 2주 정도의 긴 refresh token 2개를 발급한다.
refresh token만 데이터베이스에서 안전하게 관리하고, refresh token이 탈취되면 데이터베이스에서 해당 token의 정보를 지워버린다.
but! access token이 유효한 동안은 바로 차단할 방법이 없다.
정말 유익한 글이었습니다.