Web Authentication(인증)_세션/쿠키방식

denmark-choco·2020년 7월 29일
3

code-states_IM_8주차

목록 보기
4/4
post-thumbnail

인증이 필요한 이유

Authentication(인증)은 웹에서 중요한 절차이다. 어떤 사용자가 서비스를 사용하는지 추적이 을 하는 등 개인정보를 다루는 과정이 포함되어 있어서 타인의 정보를 보호하기 위해 필수적인 파트이다.

인증은 프론트엔드의 관점에서 봤을 때 사용자의 로그인, 회원가입과 같이 사용자의 도입부분을 가르키고, 서버사이드 관점에서 봤을 때는 모든 API요청에 대해 사용자를 확인하는 작업을 가르킨다.

Session(세션)

서버와 클라이언트의 연결이 활성화 된 상태를 말하며 방문자가 웹서버에 접속하게 되면 방문자의 요구에 따른 정보를 저장하는 것을 말한다. 서버상에서 정보가 관리되는 경우를 세션이라하고 브라우저의 메모리에서 관리하는 정보는 쿠키라고 한다.

사용자의 정보 중 보안상 중요한 데이터는 서버사이드에서 관리한다.

세션의 과정

  1. 사용자가 로그인페이지에서 로그인을 한다

  2. 서버에서 사용자가 보낸 정보가 존재하는 사용자인지 확인한다.

  3. 존재하는 사용자인 경우 유일한 세션id를 생성하고 사용자 id와 매핑정보를 저장한다.

  4. 클라이언트에 세션id를 쿠키로 저장하도록 전달한다.

  5. 이후에 클라이언트에서 서버로 요청발생시 서버는 Request Header의 쿠키 정보(세션 ID)를 확인하고 세션 ID와 매핑되는 id의 사용자로 인식한다.

쿠키와 세션이 필요한 이유

HTTP프로토콜은 Connectionless 하고 Stateless하다. 클라이언트가 서버로 요청을 하고 응답을 받으면 접속을 끊고 상태정보를 저장하지 않는 특징을 가지고 있다. 그렇기때문에 쿠키와 세션이 없으면 로그인 상태를 유지하지 않아서 페이지 이동을 하거나 게시판을 작성하는 등의 작업을 할때마다 로그인을 해야하는 번거로움이 발생한다.

🍪 Cookie(쿠키)

서버가 사용자의 위치에 정보를 저장하고 불러올 수 있는 수단이다. 특정 호스트에서 생성된 쿠키는 이후 모든 요청마다 서버로 쿠키를 다시 전송한다. 쿠키에는 이름, 값, 만료 날짜, 경로 정보가 들어있다.

쿠키는 Session 쿠키와 Permanent 쿠키가 있다. Session 쿠키는 브라우저를 끄면 사라지는 휘발성 쿠키이고 Permanent 쿠키는 브라우저를 꺼도 사라지지 않는 쿠키이다.

Response Header의 Set-Cookie 속성을 사용하면 클라이언트에 쿠키를 만들 수 있다.

    if (request.method === "GET" && request.url === "/login") {
      // 키는 login 값은 kimcoding 으로 설정
      if (!request.headers.cookie) {
        // Request 헤더에 쿠키 정보가 없는 경우
        response.writeHead(200, {
          "Set-Cookie": "login=kimcoding",
        });
      }

      response.write(fs.readFileSync("client/mypage.html"));
      request.pipe(response);
    } 

이렇게 쿠키를 전달하면 클라이언트의 네크워크에서 쿠키가 전달된 것을 아래의 이미지에서 확인 할 수 있다. 전달한 정보가 그대로 노출이 되고 있다. 보안상 매우 취약한 상태이다. 이러한 이유로 해싱이 필요하다.

Token(토큰)

인증을 위해 사용되는 암호화 된 문자열을 말한다. 유저의 활성화 여부를 신경쓰지 않고 넘겨진 요청에 담겨진 토큰의 정합성만을 확인한다.

    if (isAuthorized(credential)) {
      // 로그인이 성공한 경우
      // 로그인에 성공할 경우, 세션을 생성해야 합니다.
      // 서버에 세션이 생기고, 사용자에 브라우저에 토큰과 함께 쿠키를 발급하면,
      // 브라우저는 로그인 상태를 유지할 수 있게 됩니다.
      // session_id를 발급합니다. session_id 값은 token으로 지정하십시오.
      let token = SHA256(credential.username).toString();
      // console.log(token);
      // 67253d81419b5b71210da49a3cd144f3c5c023940f6ba6d4d34e0380e250a47e
      SESSIONS.push(token);
      response.writeHead(200, {
      "Set-Cookie": `session_id=${token}`,
         });

      https: response.write(fs.readFileSync("client/mypage.html"));
      response.end(credential.username + "님 환영합니다.");
    } 

토큰으로 정보를 해싱한 후 로그인을 하면 클라이언트의 네트워크에서도 암호화된 토큰으로 확인된다.

Encryption(암호화)

일련의 정보를 임의의 방식을 사용하여 다른 형태로 변환하여 해당 방식에 대한 정보를 소유한 사람을 제외하고 이해할 수 없도록 알고리즘을 이용해 정보를 전달하는 과정이다.

Hashing(해싱)

어떠한 문자열에 임의의 연산을 적용하여 다른 문자열로 변환하는 것을 말한다. 민감한 사용자의 정보를 노출시키지 않고 알아볼 수 없는 문자열로 변환해서 클라이언트와 서버가 주고 받는 경우 보안을 높인다. 해싱은 주로 서버사이드 내에서 이루어진다.

해싱은 모든 값을 계산하는데 오래걸리지 않으면서 고유한 값을 가져야한다.

Salting

해시 하려는 값에 추가하는 값이다. 암호화를 위해 해싱을 했지만 해싱알고리즘을 알고 있는 순간 정보의 원본을 얻을 수 있다. 원본값을 지키기 위해 해싱 전에 값을 추가해서 알고리즘을 알고 있더라도 원본을 알 수 없게 하기 위한 안전장치이다.

Crypto ( NodeJS )

NodeJS에 내장되어 있는 암화화모듈이다. 크립토 모듈을 불러와서 createHash 메소드를 사용한다.

  • createHash 메소드 : 인자로 알고리즘을 받는다.

  • update 메소드 : 암호화할 데이터를 넣어준다.

  • digest 메소드 : 어떤 인코딩 방식으로 암호화된 문자열을 표시할지를 정해준다. base64, hex, latin1 등의 방식이 있는데 base64가 짧아서 더 선호된다.

const crypto = require('crypto');

crypto.createHash('sha512').update('비밀번호').digest('base64'); 
// 'dvfV6nyLRRt3NxKSlTHOkkEGgqW2HRtfu19Ou/psUXvwlebbXCboxIPmDYOFRIpqav2eUTBFuHaZri5x+usy1g=='
crypto.createHash('sha512').update('비밀번호').digest('base64'); 
// 위와 같은 결과
crypto.createHash('sha512').update('비밀번호').digest('hex'); 
// '76f7d5ea7c8b451b773712929531ce92410682a5b61d1b5fbb5f4ebbfa6c517bf095e6db5c26e8c483e60d8385448a6a6afd9e513045b87699ae2e71faeb32d6'

이경우에는 보안에 취약해서 사용하지 않는 방법이다. 이것을 보안해서 createHmac메소드의 두번째 인자에 salt값을 추가하여 사용한다.

const crypto = require('crypto');
 
const secret = 'abcdefg';
const hash = crypto.createHmac('sha256', secret)
                   .update('I love cupcakes')
                   .digest('hex');
console.log(hash);
// Prints:
//   c0fa1bc00531bd78ef38c628449c5102aeabd49b5dc3a2a516ea6ea959d6658e

세션/쿠키 방식의 장점과 단점

장점

  • 쿠키를 매개로 인증을 거친다. 여기서 쿠키는 세션 저장소에 담긴 유저 정보를 얻기 위한 열쇠라고 보면 된다. 따라서 쿠키가 담긴 요청이 노출되더라도 쿠키자체는 유의미한 값을 가지고 있지 않아 안전하다.

  • 사용자별로 고유한 id값을 발급받기 때문에 일일이 회원정보를 확인할 필요 없이 바로 어떤 회원인지 확인할 수 있어 서버의 자원에 접근하기 용의하다.

단점

  • 쿠키가 해킹당해도 안전하다고 언급을 했지만 해커가 훔친 쿠키를 이용해 HTTP요청을 보내면 서버는 세션저장소에서 사용자로 오인해 정보를 잘못전달할 수 있다.(세션 하이재킹이라고 한다.) 이러한 경우에는 HTTPS를 사용해서 요청자체를 탈취해도 안의 정보를 읽기 힘들게하거나 세션에 유효시간을 지정하는 해결책이 있다.

  • 서버에서 세션 저장소를 사용하기때문에 서버에서 추가적인 저장공간이 필요해지고 부하도 높아진다.

참고

쿠키와 세션https://ledgku.tistory.com/72

쿠키와 document.cookiehttps://ko.javascript.info/cookie

Crypto ( NodeJS )https://slides.com/codestates/shortly-express-162#/11

Crypto ( NodeJS )_제로초https://www.zerocho.com/category/NodeJS/post/593a487c2ed1da0018cff95d

세션/쿠키 방식의 장점과 단점https://tansfil.tistory.com/58

profile
즐겁게 배우고 꾸준히 블로깅하는 주니어 개발자입니다 ;>

0개의 댓글