>  기사  >  웹 프론트엔드  >  웹 보안: 토큰 저장을 위한 localStorage와 쿠키

웹 보안: 토큰 저장을 위한 localStorage와 쿠키

WBOY
WBOY원래의
2024-08-28 06:08:02298검색

Web Security: localStorage vs cookie for storing tokens

가장 안전한 방법은 토큰을 애플리케이션 상태로 저장하는 것입니다. 그러나 사용자가 애플리케이션을 새로 고치면 토큰이 재설정된다는 점에 유의하는 것이 중요합니다. 이로 인해 사용자의 인증 상태가 상실될 수 있습니다.

그래서 토큰은 쿠키나 localStorage/sessionStorage에 저장되어야 합니다.

토큰 저장을 위한 localStorage VS 쿠키

localStorage에 인증 토큰을 저장하면 보안 위험이 발생할 수 있으며, 특히 XSS(교차 사이트 스크립팅) 취약성 측면에서 악의적인 행위자가 토큰을 도난당할 가능성이 있습니다.

HttpOnly 속성으로 구성된 쿠키에 토큰을 저장하도록 선택하면 클라이언트 측 JavaScript에 액세스할 수 없으므로 보안이 강화될 수 있습니다. 샘플 앱에서는 실제 API가 보안 강화를 위해 HttpOnly 속성을 적용하고 애플리케이션이 클라이언트 측에서 쿠키에 액세스할 수 없다고 가정하고 쿠키 관리를 위해 js-cookie를 활용합니다.

React와 Typescript를 이용한 구현

실제 API가 HttpOnly 속성을 적용하는 js-cookie를 사용하여 React TypeScript 애플리케이션에서 보안 토큰 관리를 구현하려면 다음 단계를 따르세요.

1. 설정 이해

HttpOnly 쿠키: 이 쿠키는 서버에 의해 설정되며 JavaScript를 통해 액세스할 수 없으므로 XSS 공격으로부터 더욱 안전합니다.
가정: 서버는 HttpOnly 쿠키 설정 및 관리를 처리합니다. 클라이언트측 코드는 API 응답 및 요청을 통해 토큰을 처리하는 데 중점을 둡니다.

2. React TypeScript 설정

먼저 js-cookie가 설치되어 있는지 확인하세요.

npm install js-cookie

3. 토큰 관리 설정

import React, { createContext, useContext, useEffect, useState } from 'react';
import Cookies from 'js-cookie';

interface AuthContextType {
  token: string | null;
  login: (token: string) => void;
  logout: () => void;
}

const AuthContext = createContext<AuthContextType | undefined>(undefined);

export const useAuth = () => {
  const context = useContext(AuthContext);
  if (!context) {
    throw new Error('useAuth must be used within an AuthProvider');
  }
  return context;
};

export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
  const [token, setToken] = useState<string | null>(null);

  // Assuming the token is returned from a server and set as an HttpOnly cookie
  useEffect(() => {
    const fetchTokenFromServer = async () => {
      // Example API call to authenticate and retrieve token (token management handled by server)
      try {
        const response = await fetch('/api/authenticate', {
          method: 'POST',
          credentials: 'include', // This sends the HttpOnly cookie to the server
        });

        if (response.ok) {
          setToken(await response.text()); // Assume token returned in response body for simplicity
        }
      } catch (error) {
        console.error('Error fetching token:', error);
      }
    };

    fetchTokenFromServer();
  }, []);

  const login = (token: string) => {
    // If your server returns the token via a non-HttpOnly cookie or body, store it as needed
    Cookies.set('token', token); // Only use this if the token is not HttpOnly
    setToken(token);
  };

  const logout = () => {
    Cookies.remove('token');
    setToken(null);
  };

  return (
    <AuthContext.Provider value={{ token, login, logout }}>
      {children}
    </AuthContext.Provider>
  );
};

4. 구성 요소에서 인증 컨텍스트 사용

import React from 'react';
import { useAuth } from './AuthProvider';

const Dashboard: React.FC = () => {
  const { token, logout } = useAuth();

  if (!token) {
    return <p>You are not logged in.</p>;
  }

  return (
    <div>
      <h1>Dashboard</h1>
      <p>Your token is: {token}</p>
      <button onClick={logout}>Logout</button>
    </div>
  );
};

export default Dashboard;

5. HttpOnly 쿠키 처리

클라이언트측 코드는 HttpOnly 쿠키에 직접 액세스할 수 없으므로 서버가 이러한 쿠키를 처리해야 합니다. 실제 시나리오:

로그인 : 사용자가 로그인하면 서버에서 HttpOnly 쿠키를 설정하며, 클라이언트에서 직접 관리하지는 않습니다.
API 요청: 인증이 필요한 모든 요청에는 HttpOnly 쿠키를 보내기 위한 자격 증명: '포함' 옵션이 포함되어야 합니다.

6. 서버측 구현

서버측 API가 토큰을 HttpOnly 쿠키로 설정하고 있는지 확인하세요. 예를 들어 Express.js 서버에서는 다음과 같습니다.

res.cookie('token', token, { httpOnly: true, secure: true, sameSite: 'Strict' });

7. 애플리케이션 보안

  • 쿠키가 안전하게 전송되도록 하려면 프로덕션 환경에서 항상 https를 사용하세요.

  • HTTPS를 통해서만 전송되도록 하려면 쿠키에 secure: true를 설정하는 것이 좋습니다.

  • SameSite=Strict 또는 Lax를 사용하여 CSRF 공격을 방지하세요.

읽어주셔서 감사합니다! 이 글이 도움이 되셨다면 좋아요를 눌러주세요. 질문이 있거나 논의된 주제에 대해 추가 설명이 필요한 경우 언제든지 저에게 연락해 주세요. 저는 도움을 드리기 위해 여기 있으며 여러분의 의견을 듣고 싶습니다! Twitter나 LinkedIn에서 저를 찾으실 수 있습니다. 연락을 기다리겠습니다!.

위 내용은 웹 보안: 토큰 저장을 위한 localStorage와 쿠키의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.