[Error] cookie httpOnly 옵션

조성철 (JoSworkS)·2020년 5월 26일
0
post-thumbnail

개요

클라이언트에서 유저가 로그인을 이해 아이디와 비밀번호를 입력하고 서버에 인증을 요청하게 된다. 그리고 서버에서는 요청으로 받은 body에서 아이디와 비밀번호를 취득하여 서버 데이터베이스에 있는 리소스와 비교과정을 거치고 올바른 요청일 경우, jwt 토큰을 발급하고 cookie에 'set' 하여 헤더에 담아 응답하게 된다.

클라이언트는 서버로 부터 응답받은 쿠키를 'get' 하여 안에 담겨있는 토큰을 취득하고, 이 토큰이 있을 경우, 정상적인 로그인 처리와 함께 리디렉션되는 로직이다.

문제 상황

문제는 클라이언트에서 발생하였다. 브라우저 개발자 도구의 애플리케이션을 통해 정상적으로 cookie가 들어오는 것을 확인하였고, React 컴포넌트에서 쿠키를 'get' 하였을 때, token의 정보를 얻을 수 없었다.(undefined)

해결 방법

<가정 1>: cookie의 'get' 메소드는 브라우저에서 지원하는 API이니 동기적으로 처리할 수 없다.
<가정 2>: 서버에서 cooike의 'set' 방식의 문제가 있다.

<가정 1> 부터 테스트를 진행하기 위해 cookie.get() 메소드에 대해 조사하니 mdn에 다음과 같은 설명이 있었다.

A Promise that will be fulfilled with a Cookie object containing details about the cookie, or null if the cookie was not found.

cookie.get()은 비동기적 함수이며, Promise 객체를 반환하게 된다. 즉, 이미 비동기적으로 처리되고 있는 것이다.
그렇다면 어째서 브라우저의 cookie storage 있는 토큰을 가져올 수 없었을까?

<가정 2>로 넘어가 아무래도 cookie의 'set' 옵션의 문제일 것이라고 생각하였다. 짚히는 구석이 XSS 보안을 위해 document.cookie를 통해 cookie를 취득할 수 없도록 httpOnly 옵션을 넣어 'set'하였는데, 이 부분을 제외하고 다시 테스트하였다.

jwt.sign(
  {
    userId: userData.id,
    email: userData.email
  },
  process.env.JWT_SECRET,
  {
    expiresIn: "1h"
  },
  (err, token) => {
    const inOnehour = new Date(Number(new Date()) + 1 * 60 * 60 * 1000);
    res.cookie("token", token, {
      expires: inOnehour
      // httpOnly: true,
    });
    
    res.status(200).json({
      status: "Success",
      code: 200,
      data: {
        token: token
      }
    });
  }
);

결과적으로 httpOnly 옵션을 제외하니 정상적으로 클라이언트에서 cookie에 있는 token을 가져올 수 있었다.

그러면 httpOnly 옵션은 왜 token을 가져올 수 없을까? 스택오브플로우에 다음과 같은 글이 있었다.

You can only set domain cookies for registry controlled domains, i.e. something ending in .com or so, but not IPs or intranet hostnames like localhost
출처: https://stackoverflow.com/questions/8134384/chrome-doesnt-create-cookie-for-domain-localhost-in-broken-https

도메인이 '.com'로 끝나는 일반적인 도메인에서만 쿠키가 정상적으로 작동하도록 설계되어 있다는 것이다. 이 부분을 해결하니 정상적으로 작동하였지만, 아직 쿠키의 작동방식과 디자인 컨셉에 대해 모르는 점이 많아 보완이 필요하다.

참고 자료

0개의 댓글