목표

웹의 기초이자 기본인 인증(authentication)에 대해 공부해보자

인증이 필요한 이유

거의 모든 사이트에 있는 로그인/회원가입 을 위해 인증은 꼭 필요한 절차이다. 서버 사이드에서 받은 API 요청이 어떤 클라이언트에서 온 것인지 필수적으로 알아야한다. 만약 알지 못한다면 유저의 정보가 타인에게 쉽게 넘어 가는 문제가 생기기 때문이다

HTTP 요청

현재 웹, 모바일에서 가장 많이 사용되는 통신 방식은 HTTP 이다.

문제

  • 서버와 클라이언트는 서로 이 HTTP로 통신을 하게 되는데, 이 HTTP 통신은 비연결지향의 특성이 있어서 계속 연결을 유지해주는 것이 아니라 통신 후 연결을 끊어버린다. 만약 연결이 계속 되어있다면 클라이언트에 연결될 수록 서버의 부하가 많이 커지게 된다.
  • 로그인을 했어도 다른 페이지로 넘어가면 연결이 끊기기 때문에, 페이지마다 다시 로그인을 해야한다

이러한 문제 때문에 인증 절차가 꼭 필요해졌다

인증 방식

1. 쿠키

쿠키(Cookie)란?
쿠키는 클라이언트(유저의 컴퓨터)에 저장되는 텍스트 형식의 데이터를 말한다.
이 쿠키는 HTTP통신의 헤더에 자동으로 넣어서 전송된다

HTTP 통신 요청은 설정이 기록된 헤더(header)와 데이터가 기록된 바디(body)로 구성되어있다

쿠키에 계정 정보 (ex ID, Password ...)를 담아서 서버로 전송하여 인증하는 방식이다. 페이지 이동시마다 사용자 정보를 보내게 되는데, 누가 HTTP 요청을 확인한다면 사용자의 계정 정보가 그대로 노출이 되기 때문에 보안성이 아예 없다고 보면 된다

  • 실제 서비스에서 안쓴다고 보면 된다
  • 간단한 테스트용으로는 쓸 수도 있다

2. 쿠키 / 세션

세션(session)이란?
세션은 서버에 저장되는 데이터를 말한다.

  1. 클라이언트에서 로그인 요청을 하면 서버의 세션저장소에 세션(로그인 기록)을 저장한다.
  2. 서버에서 세션 ID를 만들어서 클라이언트로 보내준다 (세션저장소가 '사물함'이면 세션ID가 '열쇠'라고 보면된다)
  3. 클라이언트에서는 이 세션ID를 쿠키에 담아놓는다.
  4. 페이지 이동시나 인증이 필요할 때마다 세션ID가 헤더에 담긴 HTTP요청을 서버로 보낸다
  5. 서버가 세션ID로 세션저장소를 확인 후 적합하면 요청을 처리해준다

장점

  • HTTP 요청이 노출이 되더라도 세션ID로는 사용자 정보를 알수가 없다
  • 고유의 세션ID로 인증을 하기 때문에 어떤 유저인지 바로 알 수 있어 리소스에 접근하기 편한다
  • 세션ID를 탈취당해도 세션에서 삭제해서 보안 피해를 줄일 수 있다

    단점

  • 서버에 추가적인 저장공간도 필요해지고, 많은 유저 접속시 서버에 부하가 걸릴 것이다

3. 토큰인증기반 (JWT)

JWT?
Json Web Token 의 약자로 인증에 필요한 정보들을 암호화 시킨 토큰을 뜻한다.

형태

토큰을 만들기 위해서는 크게 3가지, Header,Payload, Verify Signature가 필요하다

  • Header : 위 3가지 정보를 암호화할 방식(alg), 타입(type) 등이 들어간다
  • Payload : 서버에서 보낼 데이터(유저고유ID, 유효기간...)가 들어간다
  • Verify Signature : Base64 방식으로 인코딩한 Header, payload 그리고 SECRET KEY를 더한 후 서명된다

Header와 Payload는 16진수로 인코딩만 하고, Verify Signature은 [인코딩한 Header] + "." + [인코딩한 Payload]SECRET_KEY 로 해쉬한 것이다. 이 3가지 사이에 dot을 붙여 토큰을 만든다

여기서 중요한 것은 Header와 Payload 는 단순히 16진수로 인코딩한 것 이기 때문에, 디코딩하여 누구나 쉽게 확인가능하다. 하지만 Verify SignatureSECRET_KEY를 서버만 들고 있기 때문에, 토큰의 정보만 바꿔서 다른 유저의 정보를 얻지는 못한다

통신 과정

  1. 클라이언트에서 로그인 요청 시, 서버에서 토큰을 만들어 보내준다
  2. 서버에서 받은 토큰을 쿠키로 저장한다
  3. 클라이언트에서 HTTP 요청시, 서버가 헤더에 담긴 토큰을 읽어 토큰이 유효한지 확인한다
  4. 토큰을 해석하여 유효하다면, 토큰에 담긴 정보로 사용자를 파악하고 처리해준다

장점

  • SECRET_KEY로 인해 토큰을 변경하여 악용 할 수 없다
  • 서버에 따로 저장할 필요가 없어서 stateless 한 서버를 만드는 것이 장점이다

단점

  • 토큰을 탈취 당해도 한번 발급한 토큰은 막을 수 없다. 서버에서 따로 저장되어 있는게 아니라서 유효기간 끝나기를 기다려야한다... (refresh token 이란 걸로 피해를 막을 수는 있다)
  • payload가 제한적이다. 따로 암호화를 하지 않아서 유저의 중요한 정보를 넣을 수 없다
  • JWT의 길이가 길어서 인증의 필요한 요청이 많아 질수록 서버의 자원낭비가 심해진다

아래의 방식은 다음에 정리해야겠다

4.JWT - Refresh Token

5.OAuth

OAuth가 뭐지?

OAuth는 유저들이 비밀번호를 제공하지 않고 다른 사이트 계정의 정보를 받아 접근권한을 얻는 인증 방식을 말한다. 주로 Facebook이나 Naver, Github 등 으로 인증하는 것을 자주 볼 수 있다

페이스북으로 예를 들어보자

유저 -(로그인 요청)-> 사이트 -(권한부여 수락 요청)-> 유저 -(인증 및 권한부여 수락)-> 페이스북 -(성공+정보)-> 사이트 -(로그인)-> 유저

개인적으로 어렵게 정리하는 것을 안좋아하기 때문에 흐름만 이해할 수 있게 정리했다