안전하게 로그인을 구현해보자

도비굴·2023년 3월 15일
0
post-thumbnail

정보를 저장할 수 있는 저장소는 어떤 것들이 있을까?

  1. HttpOnly 속성이 설정된 쿠키: HttpOnly 속성이 설정되어 있으면, 자바스크립트를 통한 액세스가 불가능해지므로 XSS 공격 등에 대한 보안성이 높아진다.

  2. Local Storage: Local Storage는 클라이언트 측에서 제공되는 저장소로, 서버에서 생성된 토큰을 클라이언트 측에서 저장하여 사용할 수 있다. 하지만, Local Storage는 XSS 공격에 취약하며, 서버로부터 전달받은 토큰을 클라이언트 측에서 저장할 경우, 토큰을 탈취당할 가능성이 있다.

  3. Session Storage: Session Storage는 Local Storage와 유사하지만, 브라우저 세션이 종료될 때 함께 삭제되므로, 서버로부터 전달받은 토큰을 일시적으로 저장하는 용도로 사용할 수 있다.

그럼 어떤 것을 사용하는 것이 안전할까

HttpOnly 속성이 설정된 쿠키를 사용하는 것이 보안상 유리하다.

쿠키에 HttpOnly 속성을 설정하면, 자바스크립트를 통한 액세스가 불가능해지므로, XSS 공격 등에 대한 보안성이 높아진다. 또한, 서버에서 쿠키를 발급하고 클라이언트에서는 쿠키를 저장하기 때문에, 클라이언트에 저장된 토큰을 탈취당할 가능성이 상대적으로 적다.

하지만, 쿠키 역시 보안상 취약점이 있을 수 있으므로, 반드시 쿠키를 안전하게 사용하기 위한 보안 조치를 취해야 한다. 예를 들어, SSL/TLS 프로토콜을 사용하여 통신을 암호화하고, 쿠키에 대한 검증 및 보안성 검사 등을 수행해야 한다.

  1. SSL/TLS 프로토콜 사용
  2. 쿠키 유효기간 설정
  3. CSRF 공격 방지
  • CSRF(Cross-Site Request Forgery) 공격을 방지하기 위해, 쿠키에 CSRF 토큰을 저장하여 서버 측에서 유효성 검사를 수행하는 것이 좋다.
    4.쿠키를 안전한 저장소에 저장

Cookie에 토큰을 담아 로그인 구현하기

// 쿠키에 저장할 키(key)와 값(value)을 파라미터로 받아서 쿠키를 설정하는 함수
function setCookie(key, value) {
  // 쿠키 만료일자 설정 (30일 뒤)
  const expires = new Date();
  expires.setTime(expires.getTime() + (30 * 24 * 60 * 60 * 1000));

  // 쿠키 설정
  document.cookie = key + "=" + encodeURIComponent(value) + ";expires=" + expires.toUTCString() + ";path=/;HttpOnly";
}

// 로그인 시 쿠키에 토큰 값을 저장하는 함수
function login() {
  // 서버 API를 호출하여 토큰 값을 가져옴
  axios.post('/api/login', { username: 'user', password: 'password' })
    .then(response => {
      // 서버에서 전달받은 토큰 값을 쿠키에 저장
      setCookie('token', response.data.token);
    })
    .catch(error => {
      console.error(error);
    });
}

위 코드에서 setCookie() 함수는 쿠키를 설정하는 함수이며, login() 함수에서는 서버 API를 호출하여 토큰 값을 가져온 뒤, setCookie() 함수를 이용하여 쿠키에 토큰 값을 저장한다. 이때, HttpOnly 속성을 추가하여 JavaScript에서 쿠키에 접근할 수 없도록 설정한다. 이렇게 함으로써, XSS(Cross-Site Scripting) 공격 등으로부터 쿠키를 안전하게 보호할 수 있다.

// 쿠키에서 저장된 값을 가져오는 함수
function getCookie(key) {
  // 쿠키 문자열을 "; " 기준으로 분리하여 배열로 만듦
  const cookies = document.cookie.split("; ");

  // 배열을 순회하며 키(key)와 일치하는 쿠키를 찾음
  for (let i = 0; i < cookies.length; i++) {
    const cookie = cookies[i];
    // 쿠키 문자열이 키=값 형태인 경우
    if (cookie.indexOf("=") !== -1) {
      const [cookieKey, cookieValue] = cookie.split("=");
      if (cookieKey === key) {
        // 디코딩하여 반환
        return decodeURIComponent(cookieValue);
      }
    }
    // 쿠키 문자열이 키만 있는 경우
    else {
      if (cookie === key) {
        return "";
      }
    }
  }

  return "";
}

// 쿠키에서 토큰 값을 가져오는 함수
function getToken() {
  return getCookie('token');
}

// 토큰 값을 사용하여 API를 호출하는 예시
axios.get('/api/data', {
  headers: {
    Authorization: 'Bearer ' + getToken() // 토큰 값을 헤더에 추가하여 API 호출
  }
})
.then(response => {
  console.log(response.data);
})
.catch(error => {
  console.error(error);
});

위 코드에서 getCookie() 함수는 쿠키에서 저장된 값을 가져오는 함수이다. 이 함수를 이용하여 getToken() 함수를 만들어 토큰 값을 가져온 뒤, API 호출 시 토큰 값을 헤더에 추가하여 전송한다. 이렇게 함으로써, 서버는 토큰 값을 이용하여 인증을 수행하고, 쿠키를 이용하여 토큰 값을 보호할 수 있다.

profile
개발굴

0개의 댓글