Skip to content

Instantly share code, notes, and snippets.

@moonkorea00
Last active March 15, 2024 11:19
Show Gist options
  • Save moonkorea00/3fa176c70c072f4c1e96cf37e1f359c7 to your computer and use it in GitHub Desktop.
Save moonkorea00/3fa176c70c072f4c1e96cf37e1f359c7 to your computer and use it in GitHub Desktop.

정기적으로 갱신이 필요한 API 키를 검사 요청 시 자동 재발급해 접근 권한 문제 해결

  • 문제 식별 및 원인 분석

    • 익스텐션 사용 중에 검사 요청이 실패해 검사 요청에 대한 응답 확인 결과, 200 HTTP 상태 코드{error: '유효한 키가 아닙니다.'}의 응답이 반환됨

    • 네이버 맞춤법 검사 도메인에서 요청을 확인해 보니 요청 URL에 쿼리 파라미터로 기존에 없던 passportKey가 추가된 것을 확인

  • 해결 방법

    • 네이버 맞춤법 검사 도메인 HTML 내부에 맞춤법 검사기가 사용되는 script 태그 확인 결과, 모듈 내에서 passportKey가 담긴 요청 URL을 확인

      html-passportKey

    • 1차 해결 방법: 소스 코드에 passportKey 추가 (커밋)

      export async function fetchCorrections(
        editor: vscode.TextEditor,
        text: string
      ) {
        const chunk = splitChunks(editor, text);
      
        const URL = 'https://m.search.naver.com/p/csearch/ocontent/util/SpellerProxy';
        const PASSPORT_KEY = '633b693a365e691612b9a81486ebc48a4c630a60';
      
        const promises = chunk.map(value =>
          axios.get(URL, {
            params: {
              color_blindness: 0,
              q: value,
              passportKey: PASSPORT_KEY,
            },
          })
        ); 
      • 다만 passportKey가 매일 00시에 갱신되고 유효기간이 있다는 것을 추후 확인
    • 2차 해결 방법: passportKey를 네이버 도메인에서 추출해 재사용 (커밋)

      • 클라이언트에서 검사 요청 시 네이버 맞춤법 검사 도메인에 요청을 보내 응답 HTML에서 passportKey를 정규식으로 추출한 후, vscode 내장 스토리지인 workspace state에 저장해서 검사 요청마다 재사용

        workspace 스토리지에 저장한 이유: passportKey는 검사 요청마다 재사용하는 값으로 매 검사 요청마다 추가적인 API 호출을 하지 않고 최초 요청에만 유효한 passportKey를 저장해 재사용할 수 있도록 스토리지에 저장

      async function fetchPassportKey() {
        const BASE_URL =
          'https://search.naver.com/search.naver?where=nexearch&sm=top_hty&fbm=1&ie=utf8&query=맞춤법검사기';
      
        try {
          const { data: html } = await axios.get(BASE_URL);
          const match = /passportKey=([a-zA-Z0-9]+)/.exec(html);
      
          if (match) return match[1];
        } catch (err) {
          throw new Error('Failed to get key');
        }
      }
      • workspace 스토리지에 저장된 passportKey가 존재하지 않거나(익스텐션 다운로드 후 처음 사용하는 사용자) 유효하지 않은 passportKey일 경우(만료된 passportKey 등) 위 프로세스 반복
      export async function fetchCorrections(
        context: vscode.ExtensionContext,
        editor: vscode.TextEditor,
        text: string
      ) {
          let passportKey = workspace.get<string>(context, 'passport_key');
      
          if (!passportKey) {
            passportKey = await fetchPassportKey();
            if (passportKey) {
              workspace.set<string>(context, 'passport_key', passportKey);
            }
          }
          
        attemptCorrection();
        }
      • 다만 passportKey 추출을 위한 반복적인 재요청은 비정상적인 요청으로 간주될 수 있기 때문에 passportKey에 대한 재요청 시도2회로 설정하고 2회를 넘을 경우 에러 반환 후 vscode 내장 알림 기능으로 요청 결과 출력
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment