• 세션 기반의 인증은 요청을 받을 때마다 클라이언트가 보낸 세션 아이디서버(혹은 DB)의 저장소에 있는 세션 객체 안의 세션 아이디를 비교.
  • 매번 서버의 데이터를 살펴보는 것이 불편하다면?

토큰 기반 인증 (Token-based Authentication)

  • 클라이언트에서 인증 정보를 보관
  • 유저 정보를 암호화하기 때문에 민감한 인증 정보도 클라이언트에 담을 수 있다.

유저 식별 정보, 토큰 권한으로 어떤 데이터에 접근할 수 있는지(ex: 사진, 연락처에만 접근 가능) 등이 담긴 암호화된 토큰쿠키 등에 담겨 클라이언트에 전달돼서 저장됨....

JWT

  • JSON Web Token
  • 가장 대표적인 토큰 기반 인증

JWT이 이용하는 토큰

1. 엑세스 토큰 (Access Token) : 인증 증명에 사용

  • 보호된 정보들(유저의 이메일, 연락처, 사진 등)에 접근할 수 있는 권한 부여에 사용
  • 클라이언트가 처음 인증을 받으면(= 로그인 시) 엑세스 토큰, 리프레시 토큰 두 가지를 다 발급 받지만, 이후 실제로 권한을 얻는 데 사용되는 토큰은 엑세스 토큰.
  • 엑세스 토큰을 탈취당하더라도 오랫동안 사용할 수 없도록 비교적 짧은 유효기간을 주는 것이 좋다.

2. 리프레시 토큰 (Refresh Token) : 새 엑세스 토큰 발급에 사용

  • 엑세스 토큰의 유효기간이 만료되면 리프레시 토큰을 사용해 새로운 엑세스 토큰을 발급받는다. (유저가 다시 로그인 할 필요 X)
  • 만약 리프레시 토큰도 탈취당한다면 상당히 오랜 기간동안 유저에게 피해를 입힐 수 있다. (이 때문에 보안이 중요한 웹사이트 중에는 리프레시 토큰을 사용하지 않는 곳이 많음)

JWT의 구조

1. Header

  • 어떤 종류의 토큰인지
  • 어떤 알고리즘으로 시그니처를 암호화(sign) 할 지 적혀있다.
  • 아래 형식의 JSON 객체base64 방식으로 인코딩한 것
{
  "alg": "HS256",
  "typ": "JWT"
}

2. Payload

  • 서버에서 활용할 수 있는 유저의 정보
  • 어떤 정보에 접근 가능한지에 대한 권한, 또는 유저 이름 같은 개인정보 등을 담을 수 있다.
  • 아래 형식의 JSON 객체base64 방식으로 인코딩한 것

3. Signature

  • HeaderPayload를 서버의 비밀 키(솔트)와 Header에서 지정한 알고리즘을 사용해 해싱해서 생성
  • Header와 Payload를 알아내서 토큰을 위조하더라도 서버의 비밀 키를 모르면 전혀 다른 Signature가 만들어짐.

HMAC SHA256 알고리즘을 사용

HMACSHA256(base64UrlEncode(header) + '.' + base64UrlEncode(payload), secret);

JWT 사용 예시

  • JWT은 권한 부여에 굉장히 유용.
  • 어떤 정보에 접근 가능하고 접근 불가능한지 Payload에서 설정할 수 있음
  • 서로 다른 어플리케이션에도 권한을 부여할 수 있다.

Ex) A라는 앱을 Gmail과 연동시켜 이메일 정보를 가져오려고 할 때

1) A 앱의 클라이언트에서 Gmail 인증 서버에 로그인 정보(아이디, 비밀번호)를 제공해서 인증(로그인) 요청을 보낸다.
2) 성공적으로 인증 시 JWT를 발급받는다.
3) A 앱에서 JWT를 사용해 해당 유저의 Gmail 이메일을 읽거나 사용할 수 있다.


토큰 기반 인증 절차 (JWT 절차)

1. 클라이언트가 서버에 로그인 요청

  • 클라이언트가 아이디/비밀번호를 요청에 담아 서버에 보낸다. (로그인 요청)

2. 로그인 성공 시 서버가 암호화된 토큰(JWT) 생성해서 클라이언트에 전송

  • 로그인 성공 시, 엑세스 토큰리프레시 토큰을 모두 생성한다.
  • 토큰에 담길 정보(payload) : 유저 식별 정보, 토큰 권한으로 어떤 데이터에 접근할 수 있는지(ex: 사진, 연락처에만 접근 가능) 등
  • 두 토큰이 같은 정보를 담을 필요는 없다.

3. 클라이언트가 전송받은 토큰 저장

  • 저장하는 위치 : Local Storage, Session Storage, Cookie 등 다양

4. 클라이언트 요청 시 토큰 함께 전송

  • 클라이언트가 요청 보낼 때 HTTP 헤더 또는 쿠키토큰 담아 보냄.
    (엑세스 토큰HTTP 헤더 또는 바디에, 리프레시 토큰쿠키에 담는 등...다양한 방법으로 구현할 수 있다)
  • HTTP 헤더로 Authorization 헤더를 사용한다면 Bearer Authentication을 이용한다. (참고: 링크1(요약), 링크2(상세))

5. 서버는 토큰 해독 후 요청 해결/응답 보냄


토큰 기반 인증의 장점

1. 무상태성 & 확장성 (Statelessness & Scalability)

무상태성

  • 서버는 클라이언트에 대한 정보를 저장할 필요 X (토큰이 해독 되는지만 판단)
  • 클라이언트는 새로운 요청 보낼 때마다 토큰을 헤더에 포함시키면 된다.

확장성

  • 같은 토큰으로 여러 서버에서 인증 가능하기 때문에, 서버가 여러 개인 서비스일 때 더욱 편리.
    (서버에 세션 객체(인증 상태) 저장하는 세션 방식이라면 모든 서버가 해당 유저의 정보를 공유하고 있어야 함)

2. 안전하다

  • 암호화한 토큰을 사용하고, 암호화 키를 노출할 필요가 없기 때문에 안전.

3. 어디서나 생성 가능

  • 토큰을 확인하는 서버가 토큰을 만들지 않아도 된다.
  • 토큰 생성용 서버를 따로 만들거나, 다른 회사(서버)에 토큰 관련 작업을 맡길 수도 있다.

4. 권한 부여에 용이하다.

  • 토큰의 Payload 안에 어떤 정보에 접근 가능하고 접근 불가능한지 정할 수 있다.
    (ex: 서비스의 사진과 연락처 사용 권한만 부여)

0개의 댓글