세션(Session), 쿠키(Cookie), 토큰(Token), OAuth

DY·2022년 9월 13일
0

CS

목록 보기
7/10

Cookie란?

팝업에서 오늘 보지 않기, 로그인시 로그인상태유지, 구글추천광고에 쿠키를 분석하여 띄우는경우에 사용하는 보조적인 목적으로 사용 된다. 보안적인 목적으로는 사용하지 않는다

  • 표면적인 기능은 서버에서 클라이언트의 데이터를 저장하는 방법중 하나이다.

  • 사용자가 삭제하지 않는다면 계속해서 유지하므로 장시간 보존해야 하는 정보( 로그인 정보, 카드정보 등등)저장에 적합.

  • Set-Cokkie, Cookie 프로퍼티를 통해 전달.

  • 쿠기는 key- value 형태로 구성되어있고 쿠키 전송을 위한, 쿠키보존을 위한 여러가지 옵션들이 있다.

    • Domain

      • 클라이언트 쿠키의 도메인 옵션과 서버 도베인이 일치해야 쿠키를 전송 할 수 있다. naver.com에서 받은 쿠키를 google.com에 전송하는 일을 막을 수 있다.
    • Path

      • 설정된 경로로 요청을 해야 쿠키 전송이 가능하게 함.
    • MaxAge or Expires option

      • 영속성 쿠키 : MaxAge, Expires옵션이 있는 쿠키로 개인정보가 담긴 클라이언트의 쿠키 보존(유효)기간을 설정해서 클라이언트가 외부 pc를 사용시에 안전하게 이용할 수 있게 함.
      • session 쿠키 : MaxAge, Expires옵션이 없는 쿠키로 브라우저가 실행중일 때만 사용가능한 임시생성쿠키. 브라우저가 종료하면 이 쿠키는 삭제된다.
    • Secure

      • true로 설정하면 HTTPS를 이용하는 경우에만 쿠키를 전송할 수 있다.
    • HttpOnly

      • 자바스크립트에서 브라우저의 쿠키에 접근여부를 결정하는 옵션. 쿠키는 \
    • SameSite

      • CORS옵션에 따라 서버가 쿠키를 전달할지 말지 결정한다.
Set-Cookie':[
            'cookie=yummy', 
            'Secure=Secure; Secure',
            'HttpOnly=HttpOnly; HttpOnly',
            'Path=Path; Path=/cookie',
            'Doamin=Domain; Domain=codestates.com'
        ]

Cookie와 stateless

  • 처음 접속(LOGIN)시 클라이언트가 서버에 로그인 데이터를 전달한다. 서버는 전달받은 데이터로 쿠키를 만들어서 클라이언트에 다시 전달해주고 클라이언트는 받은 쿠키를 매 HTTP요청시마다 같이 전달해준다. 이를 통해 http무상태성을 유지하면서 통신할 수 있다.
  • 쿠키는 장점도 많지만 보안에 취약해서 쿠키에 민감한 정보를 담는건 지양해야한다.

Session

클라이언트가 웹페이지에 로그인을 했다면 서버는 클라이언트가 로그인에 성공했다는걸 알고 있어야 하고 클라이언트는 로그인에 성공했다는걸 증명할 수단을 가지고 있어야 한다.

  • 세션 : 사용자가 인증에 성공한 상태를 말함.

  • 세션상태라면 서버는 DB나 in-memory에 정보를 저장한다.

    • 세션을 구분하는 세션ID는 필수로 만들어지고 이외에 필요한 정보를 저장한다.
    • Session ID는 세션상태를 증명하는 수단으로 사용한다 따라서 서버, 클라이언트 둘다 가지고 있게 된다.
      • 클라이언트는 이 Session ID를 쿠키에 저장해서 사용한다.
      • 서버는 클라이언트에서오는 Session ID를 판별해서 인증이 된 ID에게만 데이터를 주고받는다
      • 쿠키의 단점과 마찬가지로 Session ID를 담고있는 쿠키가 해킹되면 해커는 서버와 통신이 가능해진다.
  • 로그아웃시에는 서버에서 session정보를 삭제하고 클라이언트에서는 cookie를 갱신, 삭제한다.

  • session은 secret옵션의 비밀키를 이용해 session ID를 암호하여 클라이언트에 전달한다.

  • 서버에서 로그인정보를 가져있기 때문에 로그인이 되어있다면 어느 디바이스에서 접속하더라도 접속되어있는 상태인지 알 수 있고, 서버측에서 일방적으로 로그인을 끊을 수 있다.

  • Node.js에서는 express-session 모듈이 존재하고 Session을 위한 미들웨어 이다.
    https://github.com/expressjs/session#reqsession

단점

  • 클라이언트마다 서버에 session을 저장하고 있어야 하기 때문에 서버가 과부화가 걸리고, 유지 비용이 많이든다.
  • 쿠키의 보안상 단점을 완벽히 해결하지 못한다.

Token

배경

  • 세션인증방식은 서버의 DB를 통해서 하기 때문에 서버의 부담을 줄여주기위해 고안해낸 방법
  • 유저의 정보를 서버가아닌 클라이언트에 저장을 하고, 서버의 비밀키로 암호화하여 데이터를 서명하기 때문에 토근 해킹되어 변경되더라도 서버는 이를 알 수 있다.

JWT (Json Wdb Token)

  • 엑세스토큰과 리프레쉬 토큰으로 나뉜다.
  • 암호화된 토큰이므로 클라이언트에 보관을 해도 된다.

엑세스 토큰

  • 보호된 정보들(유저 개개인의 정보)에 접근할 수 있는 권한을 얻는데 사용하는 토큰
  • 해킹의 위험 때문에 짧은 유효기간을 주어 탈취하더라도 금방 만료되는게 특징

리프레쉬 토큰

  • 엑세스토큰이 만료될시 사용하여 엑세스토큰을 재발급받을때 필요한 토큰
  • 해킹되면 위험하기 때문에 사이트 특성을 고려해서 사용할수도 안할수도 있다.

JWT 구조

  1. Header
    • 어떤 종류의 토큰인지, 어떤 알고리즘으로 암호화 하는지
  2. Payload
    • 유저의 정보, 기타 필요한정보, 권한정보
    • 디코딩이 쉬운 base64방식으로 인코딩 하기 때문에 민감한 정보는 담지 않는게 좋다.
  3. Signature
    • Header,Payload를 base64인코딩한 값과 salt값의 조합으로 암호화된 값(서버는 비밀키가 있기 때문에 디코딩이 가능하다.)

CSRF 공격

  • 쿠키는 서버와 통신할때 헤더에 포함되어서 전송하는 데이터다. 따라서 쿠키에 refresh토큰과 access토큰 둘다 저장하면 아래와같은 공격이 가능해진다.
  1. 해커가 이미지파일에 해킹관련 js스크립트를 포함하여 관리자에게 전송하고
  2. 관리자는 해당이미지를 서버에 전송한다.
  3. 서버에서 해커가 원하는 js스크립트가 실행이 된다.
  • 위의 과정은 관리자의 아이디로 js스크립트가 전송되었기 때문에 모든 보안을 뚫고 실행이된다. 이게 CSRF공격이다.
  • 위 공격을 막기위해 access토큰을 쿠키에 저장하지 않으면 서버에서 인증이 안되므로 access토큰은 쿠키에 저장하지 않는게 좋다.

JWT 저장

  • 클라이언트는 발급받은 JWT를 local storage, cookie, state등에 저장을 한다.

  • local storage는 XSS를 방어할수 없으므로 보안상 약하다.

  • cookie는 Http only 옵션과 Secure(https)옵션이 켜져있을때는 쿠키값 읽기를 막을수 있으므로 안전하다.

  • CSRF 공격을 염두하여 Refresh 토큰은 cookie에 저장하고 access토큰은 변수에 저장한다.

  • access토큰이 탈취되면 유저정보는 탈취 당한다 따라서 access토큰은 만료시간을 짧게 가져가서 보안을 높히고 cookie에저장된 refresh토큰은 탈취할 방법이 없으므로 안전하다.

장점

  • 서버는 토큰을 해석할수있으면 인증된 클라이언트라고 보기 때문에 클라이언트에 대한 정보를 저장할 필요가 없어서 세션방식에 비해 DB, 서버에 부담이 덜 간다.
  • 여러 서버에 분산적으로 쓸수있기 때문에 확장성과 유지보수에 좋다
  • 암호화된 토큰을 사용하기 때문에 보안상으로 좋다.
  • 권한부여에 용이하다.
    • payload안에 어떤 정보에 접근 가능한지 정의할 수 있다. 따라서 토큰의 종류에 따라 서버가 클라이언트들이 접근할 수 있는 정보의 범위를 한정할 수 있어서 클라이언트들을 등급에 따라 관리 할 수 있다.

OAuth

  • 토큰을 기반으로 직접 서버에서 인증과 관련된 로직을 처리할 필요없이 인증을 중개하는 외부 서버를 이용한 Oauth 기술로 내서버가 아닌 외부서버에서 사용자 인증처리를 맡기는 것을 말함.
  • OAuth방식을 사용하면 사용자정보를 이미 가지고있는 웹서비스(Google, 카카오 등)에서 사용자의 인증을 대신 해주고, 토큰을 발급한뒤 내 서버에서 사용,인증이 가능하다.(간편 회원가입, 로그인같은 기능)
  • 클라이언트는 처음 Auth Server에게서 Authiruzation code를 전달받고 이후 이용하고자 하는 서비스의 서버랑 통신하여 데이터를 주고받는다.
Resource Owner: 사용자이며 정보 제공자이기도 하기 때문에 Resource Owner라고 합니다.
Client: Resource Owner를 대신하여 보호된 리소스에 액세스하는 애플리케이션입니다.
Local Server: Client의 요청을 수락하고 응답할 수 있는 서버입니다.
Resource Server: 사용자의 정보를 저장하고 있는 서버입니다.
Authorization Server: 인증을 담당하고 있는 서버입니다. Access Token을 발급하는 인증 서버입니다.
Authorization Grant: Client가 Access Token을 얻는 방법을 의미합니다. 다음과 같은 방법들이 주로 사용됩니다.
Authorization Code Grant Type
Refresh Token Grant Type
Authorization Code: Authorization Grant의 한 타입으로 Access Token을 발급받기 위한 Code를 의미합니다.
Access Token: 보호된 리소스에 액세스하는 데 사용되는 인증 토큰입니다. 이 Access Token으로 이제 Resource Server에 접근할 수 있습니다.
Refresh Token: 발급받은 Access Token이 만료될 시 Refresh Token을 통해 새로운 Access Token을 받급받을 수 있습니다.

Authorization Code Grant Type

출처 : 코드스테이츠
  • 5에서 refresh, access token둘다 요청하고 받음

Refresh Token Grant Type

  • access token이 만료되었을때 사용
출처 : 코드스테이츠

github 인증과정

  • 깃허브에 이용할 사이트를 등록해야함

참고

https://jwt.io/
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie
https://www.oauth.com/oauth2-servers/accessing-data/obtaining-an-access-token/

profile
화면에 보이는 모든것에 관심이 있습니다. 개발하면서 고민했던것들, 공부했던걸 기록하는 저장소입니다.

0개의 댓글