[TIL] Day58- 인증/보안(3)

공부중인 개발자·2021년 6월 30일
0

TIL

목록 보기
58/64
post-thumbnail

토큰기반인증(JWT)

토큰기반인증을 쓰는 이유

세션기반 인증은 서버orDB에 유저 정보를 담는 방식
매 요청마다 서버orDB를 확인해야함 이 부담을 덜 방법을 고안
대표적인 토큰기반 인증 -> JWT(JSON Web Token)

토큰기반 인증은 클라이언트에 인증 정보를 보관하는 방법
클라이언트는 XSS 나 CSRF 공격에 노출 될 위험이 있으므로 민감한 정보는 담으면 안됨

하지만 토큰기반 인증은 클라이언트에 담는데?

토큰은 암호화한 상태로 담을 수 있고, 암호화로 인해 클라이언트에 담을 수 있음

JWT란?

JSON Web Token
Json 포맷으로 사용자에 대한 속성을 저장하는 웹토큰

  • JWT 구조

aaaaaa.bbbbbb.cccccc
header.payload.signature

  1. header

    • 토큰의 종류
    • 암호화하는 방법(알고리즘)
  2. Payload

    • 유저의 정보
    • 권한 부여 여부
    • 기타 필요정보
  3. Signature

    • Header, Payload를 base64인코딩한 값과 salt값의 조합으로 암호화한 값

HMACSHA256(base64UrlEncode(header) + '.' + base64UrlEncode(payload), secret);
header와 payload를 인코딩하고 secret이라는 salt값을 넣어 HMAC SHA256 알고리즘으로 암호화한 코드 위와같은 방식으로 signature를 만들 수 있다.

토큰기반 인증 절차

  1. 클라이언트 -> 서버 클라이언트가 아이디와 비밀번호를 서버로 보냄

  2. 서버 서버가 아이디와 비밀번호가 DB와 일치하는 지 확인

    • access/refresh 두개의 토큰을 모두 생성
    • 토큰에 담길 정보(Payload)는 유저를 식별할 정보, 권한이 부여된 카테고리등
    • 두개의 토큰에 같은 정보를 담을 필요 X
  3. 서버 클라이언트에게 보낼 암호화된 토큰(JWT 토큰)을 생성

  4. 서버 -> 클라이언트 클라이언트에게 암호화된 토큰을 전송

    • 클라이언트가 토큰을 저장하는곳 local storage, cookie, react_state 같이 다양한 곳에 저장가능
  5. 클라이언트 -> 서버 헤더에 {authorization:"JWT_TOKEN"} 암호화된 토큰을 담아서 정보를 요청함

    • bearer authentication을 이용
  6. 서버 암호화된 토큰을 받아서 해독

  7. 서버 -> 클라이언트 해독한 결과 서버에서 발급한 토큰이 맞는 경우 클라이언트에서 보낸 요청에 대한 응답을 해줌

토큰기반 인증의 장점

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

서버가 클라이언트에 대한 정보를 저장할 필요X (토큰의 해독여부만 판단)
클라이언트는 새로운 요청을 보낼때마다 헤더에 토큰을 포함하면 됨(여러개의 서버를 가지고 있는 서비스일 때 더 좋음 같은 토큰으로 여러 서버에 인증 가능)

  1. 안전

암호화한 토큰을 사용하고, 암호화 키를 노출 할 필요가 없으므로 안전

  1. 어디서나 생성가능

토큰을 확인하는 서버가 토큰을 만들이유 없음
토큰 생성용 서버를 만들거나, 다른회사의 토큰관련 작업을 맡겨도 됨

  1. 권한 부여에 용이

토큰의 payload 안에 어떤 정보에 접근 가능한지 정할 수 있음(토큰에서 권한을 부여 해주는것이라서 필요한 부분의 권한만 부여해주면 된다)

OAuth2

OAuth2.0은 인증을 위한 표준 프로토콜의 한 종류
보안 된 리소스에 액세스하기 위해 클라이언트에게 권한을 제공(Authorization)하는 프로세스를 단순화하는 프로토콜 중 한 방법

회원가입할 때 구글이나 네이버아이디를 통해서 회원가입하는 것같은 소셜로그인이 OAuth를 이용하는 방법 중 하나
보안상의 이점도 가지고 있음 검증되지 않은 App에서 OAuth를 사용하여 로그인한다면, 직접 유저의 민감한 정보가 App에 노출될 일이 없고 인증 권한에 대한 허가를 미리 유저에게 구해야 되기 때문에 더 안전

OAuth에서 꼭 알아야 할 용어

  • Resource Owner : 액세스 중인 리소스의 유저 // 구글 로그인을 통해 앱을 사용하는 나

  • Client : Resource owner를 대신하여 보호된 리소스에 액세스하는 응용프로그램 // 앱

  • Resource server : client의 요청을 수락하고 응답할 수 있는 서버 // 앱의 서버

  • Authorization server : Resource server가 액세스 토큰을 발급받는 서버 // 구글 로그인 서버

  • Authorization grant : 클라이언트가 액세스 토큰을 얻을 때 사용하는 자격 증명의 유형 // 사용권한 확인(확인필요 잘모르겠음)

  • Authorization code : access token을 발급받기 전에 필요한 code // 구글 로그인서버가 클라이언트에게 주는 코드

  • Access token : 보호된 리소스에 액세스하는 데 사용되는 credentials // 클라이언트가 서버에게 Authorization code를 전달하고 전달받은 코드를 서버가 구글 로그인서버로 전송하면서 요청하는 것

  • Scope : scope는 토큰의 권한을 정의

소셜 로그인의 흐름

  1. 클라 -> OAuth Authorization code요청(google아이디로 로그인버튼을 클릭하면 구글로그인 후 권한을 설정함)

  2. OAuth -> 클라 유저가 본인임을 확인하고 권한 설정에 동의하면 Authorization code를 부여

  3. 클라 -> 서버 클라는 받아온 Authorization code를 서버에게 전달

  4. 서버 -> OAuth 클라로 부터 받은 Authorization code를 OAuth에 보내서 제대로 된 코드인지 파악하며 제대로된 코드라면 Access Token 발급 요청

  5. OAuth -> 서버 서버로 부터 받은 Authorization code가 2번에서 부여한 code가 맞다면 서버에게 Access Token 부여

  6. 서버 -> 클라 OAuth로부터 받아온 Access Token을 클라이언트에게 전달


OAuth는 흐름을 파악하기가 정말 어려웠다. 하지만 나름 재밌었다고 생각하고 싶다. 백엔드 모든 것이 중요하지만 내가 생각했을 때 가장 중요한 부분은 보안이라고 생각이 든다.

profile
열심히 공부하자

0개의 댓글