토큰 기반 인증

Purple·2021년 11월 23일
0

TIL

목록 보기
60/73

1. 토큰 기반 인증이 필요한 이유

  • 세션 기반인증은 서버(혹은 DB)에 유저 정보를 담는 인증 방식인데, 이는 유저가 민감하거나 제한된 정보를 요청할 때마다 서버에서 서버가 가지고 있는 세션 값과 일치하는지 확인한다. 매 요청마다 DB를 살펴보는 것도 불편하고 부담되기 때문에 탄생한 인증이 토큰기반 인증이고, 이 중에서도 가장 대표적인 토큰은 JWT (JSON Web Token)이다.

  • 토큰은 유저 정보를 암호화한 상태를 가지고 있고, 이를 암호화 했기 때문에 클라이언트에 담아도 XSS,CSRF 공격에 노출될 위험이 없다.

2. JWT의 종류

2-1. Access Token & Refresh Token

  • Access token은 보호된 정보들( 유저의 이메일, 연락처, 사진 등)에 접근할 수 있는 권한부여에 사용한다. 클라이언트는 처음 인증을 받게 될 때(로그인 시), access, refresh token 두가지를 다 받지만, 실제로 권한을 얻는데 사용하는 토큰은 access token이다.
  • access token은 보안상의 이유로 짧은 유효 기간을 가지고 있다. access token의 유효기간이 만료된다면 refresh token을 사용하여 새로운 access token을 발급 받는다. 이때, 유저가 다시 로그인할 필요는 없다.
  • Refresh Token은 access token보다 유효기간이 길다.

2-2. JWT 구조

  • JWT의 구조는 . 으로 구분하여 3부분이 존재한다.

2-2-1. Header

  • Header는 이것이 어떤 종류의 토큰인지(예를들어 JWT인지),어떤 알고리즘으로 sign(암호화)했는지의 정보를 가지고 있다. JWT의 경우 JSON형태로 적혀있다. 이 JSON 객체를 base64 방식으로 인코딩하여 위의 aaaa와 같이 완성이 되는 것이다.
	{
		“alg” : “HS256”,
		“typ” : “JWT”
	}

2-2-2. Payload

  • 정보가 담겨있다. 어떤 정보에 접근 가능한지에 대한 권한을 담을 수 있고, 사용자의 유저 이름 등 필요한 데이터는 payload에 담아 암호화시킨다. 물론 암호화 (헤더에서 정의한)가 될 정보지만, 민감한 정보는 되도록 담지않고 최소화 하는것이 좋다. 아래의 payload도 base64로 인코딩하여 JWT 의 두번째 블록을 완성시킬 수 있다.
	{
		“sub” : “someInformation”,
		“name” : “phillip”,
		“iat” : 15253692
	}

2-2-3. Signature

  • base64로 인코딩된 첫번째, 두번째 블록이 완성되었다면, signature에는 원하는 비밀키(암호화에 추가할 salt)를 사용하여 암호화한다. base64인코딩은 누구나 쉽게 디코딩을 할 수 있지만, 서버에서만 사용하는 비밀키를 모르면 해독하기 어렵게된다.
  • 예를 들어 만약 HMAC SHA256 알고리즘(암호화 방법 중 하나)을 사용한다면 signature는 아래와 같다.
HMACSHA256(base64UrlEncode(header) + '.' + base64UrlEncode(payload), secret);

2-2-4. 그 외 Information

  • JWT는 JSON형태로 표현하는 것인데, JSON은 “\n”등 개행문자가 있어, REST API 호출시 HTTP Header에 넣기가 불편하다. 그래서, JWT에서는 JSON 문자열을 BASE64 인코딩을 통해서 하나의 문자열로 변환한다.

3. 토큰기반 인증 절차

  1. 클라이언트가 서버에 아이디/비밀번호를 담아 로그인 요청을 보낸다.
  2. 서버는 아이디/비밀번호가 일치하는지 확인하고, 클라이언트에 보낼 암호화된 토큰을 생성한다.
    • access/refresh 토큰 모두 생성한다.
    • 토큰에 담길 정보(payload)는 유저를 식별할 정보, 권한이 부여된 카테고리( 사진,연락처, 기타 등등) 이 될 수 있다.
    • 두 종류의 토큰에 같은 정보를 담을 필요는 없다.
  3. 토큰을 클라이언트에 보내주고, 클라이언트는 토큰을 저장한다. 저장하는 위치는 local storage, cookie, react의 state등 다양하다.
  4. 클라이언트가 HTTP헤더 (authorization 헤더)에 토큰을 담아 보낸다. 이때 bearer authoentication을 이용한다.
  5. 서버는 토큰을 해독하여 ok가 되면, 클라이언틔 요청을 처리한 후 응답을 보내준다.
profile
다시 보면, 더 많은 것들이 보인다.

0개의 댓글