3 분 소요

로그인

  • 웹서버는 원래 로그인이라는 기능이 없다.
  • HTTP 프로토콜은 stateless 이다. 즉 연결성이 없다. 다시 요청을 할려면 다시 연결해야 한다. 즉 로그인 인증을 계속 해줘야한다.

인증 방식을 사용하는 이유

  • 로그인을 하고 다음페이지로 이동할 때 또 로그인을 해야하는 사이트는 아주 불편할 것이다. 이러한 불편함을 없애고 사용자가 사이트 서비스를 편하게 이용하기 위해 인증 방식을 사용한다.

쿠키 인증 방식


  • 로그인 인증을 성공하면 쿠키에 인증정보를 저장한다.
  • 이러한 쿠키와 함께 서버에 요청을 하면 로그인 인증할 필요없이 빠르게 서버와 상호작용이 가능하다.

  • 하지만 공격자가 쿠키변조 공격을 이용하여 로그인을 할 수있는 취약점이 있다. 즉 쿠키를 위조하면 공격자가 쉽게 로그인이 가능하다. 따라서 쿠키를 이용해서 로그인을 하는 것을 하면 안된다.

서버기반 인증


Session 방식

  • 유저의 정보를 서버에 저장한다.
  • 서버에 인증정보를 브라우저가 아닌 서버 측에 저장하고 관리한다.
  • 클라이언트의 인증 상태정보를 저장한다.

인증과정

  • 로그인에 성공하면 서버에서 session id 를 만든다. 그리고 이 session id를 쿠키에 담아 사용자에게 보낸다.

Session ID 를 통한 요청 과정

  • 서버에서 받은 session id와 요청을 서버에 보내면 서버는 session id를 이용하여 유저 정보를 획득한다.
  • 장점
    • 각각의 사용자는 고유의 session id 를 발급받기 때문에 일일이 회원정보를 확인할 필요가 없다.
    • 강제 로그아웃, 접속 인원 제한, 로그인 된 모든 디바이스를 서버에서 쉽게 확인이 가능하다.
  • 단점
    • 사용자 수가 늘어나면 session 저장소에 과부화가 걸린다.
    • 서버에서 세션 저장소를 위한 추가적인 저장공간이 필요하다.
    • 확장성이 띄어나지 않다. 서버가 늘어나면 세션 저장소를 외부로 분리하는 작업을 해야한다. 외부로 안보내면 세션 불일치 문제를 겪는다.
    • 제 3자가 session id 가 들어있는 쿠키를 탈취한 후 이 쿠키를 이용해 HTTP 요청을 보내면 서버는 사용자를 오인해 정보를 전달하게 된다.(하이재킹 공격)
  • 하이재킹 공격 예방
    • HTTPS 프로토콜 사용 & Session 만료시간 추가 로 어느정도 예방할 수 있다.
    • 서버 측에서 세션을 무효 처리 하면 된다.

Token 기반 인증


  • 유저의 정보를 서버에 저장하지 않는다.

JWT (JSON Web Token)

  • Access Token 으로 사용된다.
  • 필요한 정보들을 암호화 시킨 토큰을 말한다.
  • header, payload 그리고 verifiy signature 로 이루어져 있다.
  • JSON Web Tokens - jwt.io
    Pasted image 20230408185606
  • 토큰의 타입을 나타내는 typ와 암호화할 방식을 정하는 alg으로 구성되어있다.
  • alg 에는 여러가지 공개키 암호화 방식중 하나의 알고리즘을 적어주면된다. (HS256, HS512, PS256 등)
  • 디코딩어 있다.
    {
    'alg': 'HS256',
    'typ': 'JWT'
    }
    

Payload

  • 토큰에 담을 정보들이 포함된다.
  • 담는 정보의 한 조각을 클레임이라 한다.
  • 노출되기 쉬움으로 민감한 정보를 담아서는 안된다. 왜냐하면 인코딩만 되어있기 때문에 쉽게 디코딩이 가능하기 때문이다. 암호화가 걸려있는 것이 아니다.
  • 식별 하기 위한 정보를 담아두어야 한다.
  • 여러개의 클레임을 넣을 수 있다.
    • iss (Issuer) : 토큰 발급자
    • sub (Subject) : 토큰 제목, 토큰에서 사용자에 대한 식별값이 됨
    • aud(Audience) : 토큰 대상자
    • exp (Expiration Time) : 토큰 만료 시간
    • nbf (Not Before) : 토큰 활성 날짜
    • iat (Issued At) : 토큰 발급 시간
    • ti (JWT Id) : JWT 토큰 식별자
    • 위의 크레임 또는 직접 추가해도 상관 없다.
      {
      'iss': 'asdfasdf'
      ..
      'my_custom': 'customm'
      }
      

Verify Signature

  • Header와 Payload가 위변조되지 않았다는 사실을 증명하는 문자열이다.
  • Base64 로 인코딩된 header 와 payload를 합친후 비밀키로 암호화를 진행한다.
  • 암호화 알고리즘은 헤더에 적힌 알고리즘 방식을 사용해야한다. ```Verify_Signature alg = HS256 HMACSHA256( base64UrlEncode(header) + “.” + base64UrlEncode(payload), 256 비밀키 )

alg = PS512 RSAPSSSHA512(…) ```

최종적으로 발급된 토큰(Access Token)

  • Header.Payload.Signature 형태가 된다.
    Pasted image 20230408191044
  • 제 3자가 토큰의 payload 정보를 변경하여 보내어도 비밀키를 알지 못하여 signature 부분 은 수정을 못한다. 따라서 서버는 payload에 변화가 있다는 것을 쉽게 탐지할 수 있다.

인증과정

발급받은 토큰을 이용한 요청 과정

  • Access Token 을 검증 할 때 서버의 공개키를 이용한다. Verify Signature 부분을 공개키로 복호화 하고 header와 payload 부분을 비교한다. 이상이 없으면 검증을 성공적으로 통과한 것이다.

  • 장점
    • 간편하다. 세션 저장소 처럼 별도의 저장소가 필요없다.
    • JWT 발급 후 검증만 하면된다.
    • 확장성이 띄어나다. 서버가 늘어나면 세션 저장소를 외부로 분리하는 작업을 해줘야한다. 하지만 토큰은 서버에 저장을 안하여 이러한 문제로 부터 자유롭다.
    • 서버의 부담이 세션 방식보다 유리하다. 따로 저장소를 둘 필요가 없기 때문이다.
  • 단점
    • 세션키와 마찬가지로 사용자 토큰을 제 3자가 훔치고, 훔친 토큰을 이용하여 HTTP 요청을 보내면 서버는 사용자를 오인해 정보를 전달하게 된다.
    • 토큰이 한번 제 3자에게 탈취되면 해당 토큰이 만료되기 전까지 속수무책으로 피해를 입을 수 밖에 없다.
    • 세션 방식보다 훨씬 더 많은 네트워크 트래픽을 사용한다. 왜냐하면 head, payload, verify signature 을 사용하여 토큰을 만들기 때문이다.

Refresh Token 을 이용한 인증과정

  • Access Token 이 탈취 당할 것을 대비하여 유효기간을 짧게 하고 Access Token 이 만료되었을 때 새로 발급요청하는 열쇠가 된다.
  • Refresh Token 은 긴 유효기간을 가진다.
  • 예를 들면 Access Token 의 유효기간은 1시간, Refresh Token 의 유효기간은 1주라 하자. 그러면 Access Token 이 만료되더라도, Refrech Token 을 이용하여 Access Token을 새롭게 발급받으면 된다.
  • Access Token 과 같은 JWT 형태이다.

  • 장점
    • Access Token 을 가지고 있을 때 보다 안전하다.
  • 단점
    • 구현 방법이 복잡하다.
    • Access Token 이 만료될 때마다 새롭게 발급하는 과정에거 HTTP 요청 횟수가 많아진다.

참고 사이트

댓글남기기