Post

원티드 프리온보딩 - 로그인 기능 구현하기 2 (내용)

원티드 프리온보딩 - 로그인 기능 구현하기 2강 복습

실습 코드

토큰(Token)이란?

사용자 신원을 알 수 있는 인증키,

a piece of data that is used to represent and replace another one, in order to prevent private information being seen by someone who is not allowed to do so :

로그인에 토큰을 사용해야하는 이유

서버는 무상태성(stateless)기 때문에 상태 저장을 하지 않기 때문에, 토큰을 사용해 사용자의 정보를 저장하기 위해

  • 토큰을 사용하지 않는다면 물건을 장바구니에 추가할 때도, 장바구니로 이동할 때도 로그인을 계속해줘야함

로그인의 흐름

loginflow

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

  2. 서버에서 클라이언트에 토큰 발급 및 전달

  3. 클라이언트에서 토큰 보관

  4. 클라이언트에서 토큰을 사용해 서버에 요청

실제 서비스에서의 구조

loginflow2

유저 진입 후 토큰을 가지고 있는 여부에 따라 다음 단계 결정

1
2
3
4
5
6
1-1. 토큰이 있는 경우 서버에 token의 유효성을 확인
  - 토큰이 유효하다면 로그인 성공!
  - 토큰이 유효하지 않다면 로그인 진행

1-2. 토큰이 없다면 로그인 진행
  - 사용자의 id와 비밀번호를 받아 서버에 인증 정보를 확인하고, 서버에서 새로운 token을 발급받아서 로그인 성공!

JWT (Json Web Token)

내부에 들어 있는 내용

1. Header

  • 암호화 규칙 (alg) : 암호화 알고리즘_어떻게 암호화 할 것인지에 대한 내용
  • 토큰 타입 (typ)
1
2
3
4
{
  "alg": "HS256",
  "typ": "JWT"
}

2. PAYLOAD

  • 데이터 (클레임)
  • sub: 토큰 제목
  • iat: 언제 발급되었는지
1
2
3
4
5
{
  "sub": "1234567",
  "name": "John Doe",
  "iat": 1516239022
}

3. SIGNATURE

  • 암호화를 위한 데이터
  • MY_SECRET_KEY : 서버만 알고 있고, 서버와 비교하여 유효성 검사할 데이터
1
2
3
4
5
HMACSHA256(
    base64UrlEncode(header) + "." +
    base64UrlEncode(payload),
    MY_SECRET_KEY_1234!@#
) secret base64 encoded

해싱이란?

  • 단방향 암호화 기법
  • 평문(암호화 되지 않은 정보)를 해시함수(해시 알고리즘)을 이용해 고정된 길이의 암호화된 문자열로 바꾸는 것

실제로 JWT 관련 동작이 일어나는 곳

loginflow3

- 토큰이 유효한지 확인할 때

  • 클라이언트가 저장된 token을 서버에 보내고, 서버는 유효성 검증을 한 결과를 클라이언트에게 반환

- 로그인 진행할 때

  • 사용자가 입력한 id와 비밀번호를 서버에 보내면, 서버는 인증 정보를 확인하고 새로운 token을 생성해서 클라이언트에 보내줌

Access Token만 사용하면 보안이 완벽할까?

  • XSS, CSRF 등을 통해 토큰을 탈취할 수 있음

onlyaccess

XSS (Cross Site Scripting)

  • 관리자가 아닌 권한이 없는 사용자가 웹 사이트에 스크립트를 삽입하는 공격 기법
  • 악의적인 사용자가 C&C 서버로 리다이렉션 하기 위해 리다이렉션 스크립트를 주입하여 중간 경유지로 활용
  • 사용자의 쿠키를 탈취하여 세션 하이재킹(Session Hijacking) 공격을 수행

xss2

CSRF (Cross-site Request Forgery)

  • 사이트 간 요청 위조
  • 사용자가 자신의 의지와는 무관하게 공격자가 의도한 행위를 특정 웹사이트에 요청하게 하는 공격
  • 악성 메일이나, 스팸 문자의 링크를 클릭하면 사용자의 정보를 탈취하는 공격

JWT 보관 방식과 보안

Access Token : 재접근할 수 없는 런타임 메모리에 저장

Refresh Token: HttpOnly Cookie로 발급

Refresh Token

  • 새로운 토큰을 생성하는 용도로만 사용되는 token (일회용 토큰)

HttpOnly Cookie

  • https로만 접근이 가능하고, javascript로는 접근이 불가능
  • GET,POST (읽고 쓰기)가 모두 불가능
  • API에 넣어서 사용해도 RESPONSE가 오지 않음

refreshaccess

- XSS 공격 방어

tokenxss

  • HTTPS 요청으로만 사용 가능하기 때문에 (자바스크립트 사용 불가) XSS 공격으로 토큰을 탈취할 수 없음
  • 다른 방법으로 탈취하더라도 Token에 접근하기 위해서는 추가 인증이 필요함

- CSRF 공격 방어

tokencsrf

1. CSRF 공격으로 Refresh Token 재사용 시도

2. 악성사이트에서 서버로 Access Token 재발급 요청

결과

  • 만료되지 않은 Access Token 확인, 모든 토큰 무효화
  • 일회용 Refresh Token으로 토큰 재발급 요청했기 때문에 요청을 무시 (Refresh Token Rotation)

참고사이트

This post is licensed under CC BY 4.0 by the author.