CAPTCHA의 탐색적 테스트

리뷰 앱 및 로컬 개발 환경(GDK)에서 CAPTCHA를 신뢰성 있게 테스트할 수 있습니다. 항상 다음을 수행할 수 있습니다:

  • 지원되는 경우 reCAPTCHA가 나타나도록 강제할 수 있습니다.
  • 보도자료 이미지 대신 확인란을 표시하도록 강제할 수 있습니다.

테스트를 설정하려면, 이 페이지의 구성을 따르세요.

적절한 테스트 데이터 사용

스팸/CAPTCHA가 활성화된 시나리오를 테스트하는지 확인하세요. 예: 공개 스니펫을 편집하는지 확인하십시오. 공개 스니펫만이 스팸으로 확인됩니다.

피처 플래그 활성화

스팸/CAPTCHA 지원이 피처 플래그 뒤에 숨겨져 있는 경우 관련 피처 플래그를 활성화하세요.

Akismet 및 reCAPTCHA 설정

  1. reCAPTCHA 설정:
    1. GitLab reCAPTCHA 문서를 검토하세요.
    2. Google reCAPTCHA 문서의 지침을 사용하여 Google의 공식 테스트 reCAPTCHA 자격 증명을 얻으세요.
      1. 사이트 키로 다음을 사용하세요: 6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI
      2. 비밀 키로 다음을 사용하세요: 6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe
    3. 관리자 -> 설정 -> 보고서 설정으로 이동: http://gdk.test:3000/admin/application_settings/reporting#js-spam-settings
    4. 스팸 및 안티봇 보호 섹션을 확장하세요.
    5. reCAPTCHA 활성화를 선택하세요. 로그인을 위해 활성화하는 것은 필요하지 않습니다.
    6. 사이트 키비밀 키를 입력하세요.
  2. Akismet 설정:
    1. Akismet에 관한 GitLab 문서를 검토하세요.
    2. Akismet API 키를 받으세요. Akismet에서 테스트 키를 등록할 수 있습니다. 등록할 때 로컬 호스트(예: gdk.test)와 이메일을 입력해야 합니다.
    3. 예를 들어 GitLab Akismet 설정 페이지로 이동하세요: http://gdk.test:3000/admin/application_settings/reporting#js-spam-settings
    4. Akismet을 활성화하고 Akismet API 키를 입력하세요.
  3. Akismet 거짓 긍정 스팸 확인을 강제하려면, Akismet API 문서Akismet 시작 가이드 문서를 참조하여 자세한 내용을 확인하세요:
    1. 다음 단계를 사용하여 akismet-guaranteed-spam@example.com을 사용하여 스팸을 강제할 수 있습니다:
      1. 사용자 이메일 설정으로 이동하세요: http://gdk.test:3000/-/profile/emails
      2. 관리자 사용자를 위해 akismet-guaranteed-spam@example.com을 보조 이메일로 추가하세요.
      3. Rails 콘솔에서 확인하세요: bin/rails c -> User.find_by_username('root').emails.last.confirm
      4. 확인된 이메일을 기본 이메일로 변경하세요:
        1. 아바타 드롭다운 디렉터리 -> 프로필 편집 -> 기본 설정으로 이동하세요.
        2. 이메일admin@example.com을 대체하기 위해 akismet-guaranteed-spam@example.com을 입력하세요.
        3. 변경 사항을 저장하기 위해 프로필 설정 업데이트를 선택하세요.

웹 UI에서 테스트

위의 구성을 모두 설정한 후 CAPTCHA를 테스트할 수 있습니다. CAPTCHA 지원이 이미 있는 응용 프로그램 영역에서 테스트할 수 있습니다.

  • 이슈를 생성하거나 편집합니다.
  • 공개 스니펫을 생성하거나 편집합니다. 스팸 확인은 공개 스니펫만이 실행됩니다.

개발 환경에서 테스트

위의 단계를 사용하여 스팸 플래그 + CAPTCHA를 강제한 후에는 스팸으로부터 보호되는 모델/컨트롤러 작업의 동작을 테스트할 수 있습니다.

CAPTCHA 활성화된 상태에서 테스트 (조건부 허용 결정)

이러한 영역에서 CAPTCHA가 활성화된 경우 양식을 다시 제출하기 전에 CAPTCHA 팝업 모달을 해결해야 합니다:

  • 관리자 -> 설정 -> 보고서 -> 스팸
  • 안티봇 보호 -> reCAPTCHA 활성화

CAPTCHA 비활성화된 상태에서 테스트 (“거부” 결정)

CAPTCHA가 관리자 -> 설정 -> 보고서 -> 스팸안티봇 보호 -> reCAPTCHA 활성화에서 비활성화된 경우 CAPTCHA 팝업이 표시되지 않습니다. 양식을 전혀 제출할 수 없습니다.

reCAPTCHA 렌더링을 위한 HTML 페이지

note
만약 Akismet 및 reCAPTCHA 설정에 나열된 Google의 공식 테스트 reCAPTCHA 자격 증명을 사용하는 경우, CAPTCHA 응답 문자열이 중요하지 않습니다. 아무 문자열이어도 상관없습니다. 실제 유효한 키 쌍을 사용하는 경우 유효한 CAPTCHA 응답을 얻으려면 CAPTCHA를 해결해야 합니다. 이렇게 할 수 있는 것은 딱 한 번이며 만료되기 전에만 가능합니다.

GraphQL Explorer를 통해 GraphQL API를 직접 테스트하려면 (http://gdk.test:3000/-/graphql-explorer), CAPTCHA 응답 문자열을 얻으려면 이 양식을 사용하세요: public/recaptcha.html (http://gdk.test:3000/recaptcha.html):

<html>
<head>
  <title>reCAPTCHA demo: Explicit render after an onload callback</title>
  <script type="text/javascript">
  var onloadCallback = function() {
    grecaptcha.render('html_element', {
      'sitekey' : '6Ld05AsaAAAAAMsm1yTUp4qsdFARN15rQJPPqv6i'
    });
  };
  function onSubmit() {
    window.document.getElementById('recaptchaResponse').innerHTML = grecaptcha.getResponse();
    return false;
  }
  </script>
</head>
<body>
<form onsubmit="return onSubmit()">
  <div id="html_element"></div>
  <br>
  <input type="submit" value="Submit">
</form>
<div>
  <h1>recaptchaResponse:</h1>
  <div id="recaptchaResponse"></div>
</div>
<script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit"
        async defer>
</script>
</body>
</html>

스팸/CAPTCHA API 탐색적 테스트 예제

이러한 섹션은 REST 및 GraphQL API에 대한 스팸 및 CAPTCHA 동작의 다양한 시나리오를 매뉴얼으로 탐색적으로 테스트하기 위해 수행해야 할 단계를 설명합니다.

전제 조건으로, 다음을 수행해야 합니다:

  1. 개발 환경에서 스팸 및 CAPTCHA를 활성화하고 양식 제출이 CAPTCHA를 필요로 하도록 강제하기 위해 모든 단계를 수행하세요.
  2. /public 디렉터리 하위에 CAPTCHA를 렌더링하기 위한 HTML 페이지를 만들어야 합니다. 이 페이지에는 유효한 CAPTCHA 응답 문자열을 매뉴얼으로 생성하는 양식이 포함되어야 합니다. [Akismet 및 reCAPTCHA 설정](#set-up-akismet-and-recaptcha)에 나열된 Google의 공식 테스트 reCAPTCHA 자격 증명을 사용하는 경우, CAPTCHA 응답 문자열의 내용은 문제가 되지 않습니다.
  3. 관리자 -> 설정 -> 보고서 -> 스팸 및 안티봇 보호로 이동하세요.
  4. 시나리오의 요구에 따라 reCAPTCHA 활성화Akismet 활성화를 선택하거나 선택해제하세요.

다음 예제는 스니펫 생성을 사용합니다. 스니펫 업데이트, 이슈 생성 또는 이슈 업데이트를 사용할 수도 있습니다. 문제 및 스니펫만이 완전한 스팸 및 CAPTCHA 지원을 가진 모델입니다.

초기 설정

  1. API 토큰을 생성합니다.
  2. REST 명령어를 위해 터미널에서 해당 토큰을 내보냅니다: export PRIVATE_TOKEN=<your_api_token>
  3. GraphQL 쿼리를 실행하기 전에 localhost:3000의 GitLab 개발 환경에 로그인되어 있는지 확인합니다. 이는 인증된 사용자를 사용하여 GraphQL 쿼리를 실행하기 위한 권한 부여에 사용됩니다.
  4. GraphQL 예제에서는 http://localhost:3000/-/graphql-explorer의 GraphiQL 탐색기를 사용합니다.
  5. curl 명령어를 사용할 때 --include(-i) 옵션을 사용하여 상태 코드를 포함한 HTTP 응답 헤더를 출력합니다.

시나리오: Akismet 및 CAPTCHA 활성화

이 예에서는 Akismet 및 CAPTCHA가 활성화된 상황을 다룹니다.

  1. 초기 요청.

초기 요청

이 초기 요청은 CAPTCHA 응답이 제공되지 않아 실패합니다.

REST 요청:

curl --request POST --header "PRIVATE-TOKEN: $PRIVATE_TOKEN" "http://localhost:3000/api/v4/snippets?title=Title&file_name=FileName&content=Content&visibility=public"

REST 응답:

{"needs_captcha_response":true,"spam_log_id":42,"captcha_site_key":"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX","message":{"error":"Your snippet has been recognized as spam. Please, change the content or solve the reCAPTCHA to proceed."}}

GraphQL 요청:

mutation {
    createSnippet(input: {
        title: "Title"
        visibilityLevel: public
        blobActions: [
            {
                action: create
                filePath: "BlobPath"
                content: "BlobContent"
            }
        ]
    }) {
        snippet {
            id
            title
        }
        errors
    }
}

GraphQL 응답:

{
  "data": {
    "createSnippet": null
  },
  "errors": [
    {
      "message": "Request denied. Solve CAPTCHA challenge and retry",
      "locations": [
        {
          "line": 22,
          "column": 5
        }
      ],
      "path": [
        "createSnippet"
      ],
      "extensions": {
        "needs_captcha_response": true,
        "spam_log_id": 140,
        "captcha_site_key": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
      }
    }
  ]
}

두 번째 요청

이 요청은 CAPTCHA 응답이 제공되어 성공합니다.

REST 요청:

export CAPTCHA_RESPONSE="<CAPTCHA response obtained from HTML page to render CAPTCHA>"
export SPAM_LOG_ID="<spam_log_id obtained from initial REST response>"
curl --request POST --header "PRIVATE-TOKEN: $PRIVATE_TOKEN" --header "X-GitLab-Captcha-Response: $CAPTCHA_RESPONSE" --header "X-GitLab-Spam-Log-Id: $SPAM_LOG_ID" "http://localhost:3000/api/v4/snippets?title=Title&file_name=FileName&content=Content&visibility=public"

REST 응답:

{"id":42,"title":"Title","description":null,"visibility":"public", "other_fields": "..."}

GraphQL 요청:

note
GitLab GraphiQL 구현은 헤더 전달을 허용하지 않기 때문에 curl 쿼리로 작성하여야 합니다. 여기서 --data-binary를 사용하여 JSON-임베디드 쿼리 내 이스케이프된 이중 인용부호가 적절히 처리되었습니다.
export CAPTCHA_RESPONSE="<CAPTCHA response obtained from HTML page to render CAPTCHA>"
export SPAM_LOG_ID="<spam_log_id obtained from initial REST response>"
curl --include "http://localhost:3000/api/graphql" --header "Authorization: Bearer $PRIVATE_TOKEN" --header "Content-Type: application/json" --header "X-GitLab-Captcha-Response: $CAPTCHA_RESPONSE" --header "X-GitLab-Spam-Log-Id: $SPAM_LOG_ID" --request POST --data-binary '{"query": "mutation {createSnippet(input: {title: \"Title\" visibilityLevel: public blobActions: [ { action: create filePath: \"BlobPath\" content: \"BlobContent\" } ] }) { snippet { id title } errors }}"}'

GraphQL 응답:

{"data":{"createSnippet":{"snippet":{"id":"gid://gitlab/PersonalSnippet/42","title":"Title"},"errors":[]}}}

시나리오: Akismet 활성화, CAPTCHA 비활성화

이 시나리오에서는 관리 영역 설정에서 reCAPTCHA 활성화를 해제하도록 합니다. CAPTCHA가 비활성화된 경우라면, CAPTCHA가 활성화되어 성공적으로 해결되었다면 재제출할 수 있을지라도 잠재적으로 스팸으로 플래그 지정된 모든 요청은 실패합니다.

CAPTCHA가 활성화되지 않은 경우 REST 요청은 CAPTCHA가 활성화된 경우와 동일합니다:

curl --request POST --header "PRIVATE-TOKEN: $PRIVATE_TOKEN" "http://localhost:3000/api/v4/snippets?title=Title&file_name=FileName&content=Content&visibility=public"

REST 응답:

{"message":{"error":"Your snippet has been recognized as spam and has been discarded."}}

GraphQL 요청:

mutation {
    createSnippet(input: {
        title: "Title"
        visibilityLevel: public
        blobActions: [
            {
                action: create
                filePath: "BlobPath"
                content: "BlobContent"
            }
        ]
    }) {
        snippet {
            id
            title
        }
        errors
    }
}

GraphQL 응답:

{
  "data": {
    "createSnippet": null
  },
  "errors": [
    {
      "message": "Request denied. Spam detected",
      "locations": [
        {
          "line": 22,
          "column": 5
        }
      ],
      "path": [
        "createSnippet"
      ],
      "extensions": {
        "spam": true
      }
    }
  ]
}
}

시나리오: allow_possible_spam 애플리케이션 설정 활성화

allow_possible_spam 애플리케이션 설정이 활성화된 경우, API는 200 응답을 반환합니다. 유효한 요청은 성공하고 CAPTCHA가 나타나지 않으며, 요청이 스팸으로 간주되더라도 임의로 성공합니다.