본문 바로가기

카테고리 없음

ㅎㅎ

// Snippet: Real-time Authorization Header Tracker
(function trackAuthHeader() {
  const accessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...';
  
  console.log('🔍 === 인증 헤더 추적 시작 ===\n');
  
  // 1. 먼저 localStorage 설정
  localStorage.setItem('accessToken', accessToken);
  console.log('✅ localStorage 설정:', accessToken.substring(0, 30) + '...\n');
  
  // 2. 모든 axios 인스턴스를 찾아서 실시간 모니터링
  console.log('🔎 axios 인스턴스 검색 및 모니터링 설정...\n');
  
  let monitoredCount = 0;
  
  function monitorAxios(axiosInstance, name) {
    monitoredCount++;
    console.log(`📦 ${monitoredCount}. ${name} - 모니터링 시작`);
    
    // 현재 헤더 상태 확인
    console.log('   현재 헤더:', axiosInstance.defaults?.headers?.common);
    
    // 헤더 설정
    if (axiosInstance.defaults?.headers?.common) {
      axiosInstance.defaults.headers.common['Authorization'] = `Bearer ${accessToken}`;
      console.log('   ✅ Authorization 설정 완료');
      console.log('   확인:', axiosInstance.defaults.headers.common.Authorization?.substring(0, 30));
    }
    
    // interceptors 모니터링
    if (axiosInstance.interceptors?.request) {
      console.log('   🎣 request interceptor 후킹 시도...');
      
      // 기존 interceptor 개수
      const handlers = axiosInstance.interceptors.request.handlers || [];
      console.log('   기존 request interceptor:', handlers.length + '개');
      
      // 새로운 interceptor 추가 (최우선)
      axiosInstance.interceptors.request.use(
        (config) => {
          console.log('\n🚀 REQUEST INTERCEPTOR 실행:');
          console.log('   URL:', config.url);
          console.log('   Headers BEFORE:', config.headers);
          
          // 강제로 토큰 추가
          if (!config.headers) {
            config.headers = {};
          }
          
          config.headers['Authorization'] = `Bearer ${accessToken}`;
          config.headers.Authorization = `Bearer ${accessToken}`;
          
          console.log('   Headers AFTER:', config.headers);
          console.log('   Authorization:', config.headers.Authorization?.substring(0, 30));
          
          return config;
        },
        (error) => {
          console.error('   ❌ Request interceptor error:', error);
          return Promise.reject(error);
        }
      );
      
      console.log('   ✅ 새 request interceptor 추가 완료');
    }
    
    // response interceptor 모니터링
    if (axiosInstance.interceptors?.response) {
      console.log('   🎣 response interceptor 후킹 시도...');
      
      const handlers = axiosInstance.interceptors.response.handlers || [];
      console.log('   기존 response interceptor:', handlers.length + '개');
      
      axiosInstance.interceptors.response.use(
        (response) => {
          console.log('\n✅ RESPONSE 성공:');
          console.log('   Status:', response.status);
          console.log('   URL:', response.config?.url);
          return response;
        },
        (error) => {
          console.error('\n❌ RESPONSE 에러:');
          console.error('   Status:', error.response?.status);
          console.error('   URL:', error.config?.url);
          console.error('   Message:', error.message);
          
          if (error.response?.status === 401) {
            console.error('   🔴 401 Unauthorized!');
            console.error('   요청 헤더:', error.config?.headers);
          }
          
          return Promise.reject(error);
        }
      );
      
      console.log('   ✅ 새 response interceptor 추가 완료');
    }
    
    console.log('');
  }
  
  // 3. 전역에서 axios 찾기
  console.log('🌍 전역 axios 검색...\n');
  
  for (let key in window) {
    try {
      const obj = window[key];
      
      if (obj?.defaults?.headers?.common || obj?.interceptors?.request) {
        monitorAxios(obj, `window.${key}`);
      }
      
      // 중첩된 객체도 확인
      if (typeof obj === 'object' && obj !== null) {
        for (let subKey in obj) {
          try {
            const subObj = obj[subKey];
            if (subObj?.defaults?.headers?.common || subObj?.interceptors?.request) {
              monitorAxios(subObj, `window.${key}.${subKey}`);
            }
          } catch (e) {}
        }
      }
    } catch (e) {}
  }
  
  // 4. Webpack에서 axios 찾기
  console.log('📦 Webpack 모듈 검색...\n');
  
  const webpackChunk = window.webpackChunk_sovo_vo;
  
  if (webpackChunk) {
    // webpack require cache
    for (let key in window) {
      try {
        const obj = window[key];
        if (obj?.c || obj?.m) { // webpack cache
          console.log(`🔍 Webpack cache 발견: window.${key}`);
          
          const cache = obj.c || {};
          const modules = obj.m || {};
          const all = { ...cache, ...modules };
          
          for (let modId in all) {
            try {
              const mod = all[modId];
              const exp = mod.exports || mod;
              
              if (exp?.defaults?.headers?.common || exp?.interceptors?.request) {
                monitorAxios(exp, `webpack.module[${modId}]`);
              }
              
              // default export
              if (exp?.default?.defaults?.headers?.common) {
                monitorAxios(exp.default, `webpack.module[${modId}].default`);
              }
            } catch (e) {}
          }
        }
      } catch (e) {}
    }
  }
  
  console.log(`\n✅ 총 ${monitoredCount}개의 axios 인스턴스 모니터링 설정 완료\n`);
  
  // 5. fetch/XHR도 모니터링
  console.log('🎣 fetch/XHR 모니터링 설정...\n');
  
  const originalFetch = window.fetch;
  window.fetch = function(url, options = {}) {
    console.log('\n🌐 === FETCH 호출 ===');
    console.log('URL:', url);
    console.log('Options:', options);
    
    // Headers 객체 처리
    if (!options.headers) {
      options.headers = {};
    }
    
    if (options.headers instanceof Headers) {
      console.log('Headers 타입: Headers 객체');
      console.log('기존 Authorization:', options.headers.get('Authorization'));
      
      options.headers.set('Authorization', `Bearer ${accessToken}`);
      
      console.log('설정 후 Authorization:', options.headers.get('Authorization'));
    } else {
      console.log('Headers 타입: Plain Object');
      console.log('기존 Authorization:', options.headers.Authorization || options.headers.authorization);
      
      options.headers['Authorization'] = `Bearer ${accessToken}`;
      options.headers.authorization = `Bearer ${accessToken}`;
      
      console.log('설정 후 Authorization:', options.headers.Authorization);
    }
    
    return originalFetch.call(this, url, options)
      .then(response => {
        console.log('응답 상태:', response.status);
        if (response.status === 401) {
          console.error('🔴 401 Unauthorized!');
        }
        return response;
      })
      .catch(error => {
        console.error('fetch 에러:', error);
        throw error;
      });
  };
  
  const XHR = XMLHttpRequest.prototype;
  const open = XHR.open;
  const send = XHR.send;
  const setRequestHeader = XHR.setRequestHeader;
  
  XHR.open = function(method, url) {
    this._method = method;
    this._url = url;
    this._headers = {};
    return open.apply(this, arguments);
  };
  
  XHR.setRequestHeader = function(name, value) {
    this._headers[name] = value;
    return setRequestHeader.apply(this, arguments);
  };
  
  XHR.send = function() {
    console.log('\n🌐 === XHR 호출 ===');
    console.log('Method:', this._method);
    console.log('URL:', this._url);
    console.log('기존 Headers:', this._headers);
    
    // 강제로 Authorization 추가
    if (!this._headers.Authorization && !this._headers.authorization) {
      this.setRequestHeader('Authorization', `Bearer ${accessToken}`);
      this._headers.Authorization = `Bearer ${accessToken}`;
      console.log('✅ Authorization 헤더 추가됨');
    }
    
    console.log('최종 Headers:', this._headers);
    
    this.addEventListener('load', function() {
      console.log('응답 상태:', this.status);
      if (this.status === 401) {
        console.error('🔴 401 Unauthorized!');
        console.error('요청 헤더:', this._headers);
      }
    });
    
    return send.apply(this, arguments);
  };
  
  console.log('✅ fetch/XHR 모니터링 설정 완료\n');
  
  // 6. 테스트 요청 보내기
  console.log('🧪 === 테스트 시작 ===\n');
  console.log('이제 페이지를 새로고침하거나 /dashboard로 이동하세요');
  console.log('모든 네트워크 요청이 콘솔에 로그됩니다\n');
  
  // 저장
  window.__authDebug = {
    accessToken,
    monitoredCount,
    timestamp: new Date().toISOString()
  };
  
  console.log('💡 디버깅 정보: window.__authDebug\n');
})();