CORS(교차 출처 리소스 공유) 설정하기

:notebook_with_decorative_cover: 이 how-to 가이드는 Discourse에서 교차 출처 리소스 공유(CORS)를 설정하는 과정을 안내해 드립니다.

CORS는 웹 페이지의 많은 리소스(예: 폰트, JavaScript 등)가 해당 리소스가 기원한 도메인 외부의 다른 도메인에서 요청될 수 있도록 하는 메커니즘입니다.

Discourse 사이트에서 CORS를 설정하는 방법은 다음과 같습니다:

사전 요구 사항

시작하기 전에, CORS를 활성화하려면 DISCOURSE_ENABLE_CORS 환경 변수가 true로 설정되어 있어야 합니다.

이 부분에 대한 도움이 필요하시면 환경 변수 설정 방법을 참고하세요.

:sparkles: Discourse 호스팅 사이트를 사용 중이라면 이 단계는 이미 완료된 것이므로 추가적인 구성 작업이 필요하지 않습니다.

사이트 설정에 액세스하기

Discourse 관리자 패널로 이동합니다. 그곳에서 “설정” 탭으로 이동하세요.

CORS 설정 찾기

“설정” 탭에서 검색창을 사용하여 cors origin을 입력하세요. CORS와 관련된 다음 설정을 확인하실 수 있습니다:

이 설정을 사용하면 Discourse 인스턴스에 교차 출처 요청을 수행할 수 있는 도메인을 지정할 수 있습니다.

여기에는 공백으로 구분된 정확한 도메인을 입력해야 합니다. 보안 위험을 초래할 수 있으므로 와일드카드(*) 사용은 피하세요.

여러 도메인을 추가할 경우, 각 URL은 구분되어야 합니다. 예를 들어:

변경 사항 저장

필요한 변경 사항을 수행한 후, 페이지 하단의 변경 사항 저장 버튼을 클릭하는 것을 잊지 마세요.

중요 참고 사항

CORS(교차 출처 리소스 공유)를 부적절하게 구현하면 잠재적인 보안 위험이 발생할 수 있습니다. 사이트에 CORS를 활성화할 때 다음 사항을 염두에 두세요:

  • 정확한 도메인 지정: CORS 구성에서 와일드카드(*)를 사용하면 어떤 도메인이라도 서버와 상호작용할 수 있게 되어 상당한 보안 위험이 됩니다. 정확한 도메인을 지정하는 것이 권장됩니다.
  • 노출 데이터 최소화: CORS는 신뢰할 수 있는 외부 도메인에서 필요한 데이터만 노출되도록 설정해야 합니다. 사용자가 제어하지 않는 사이트에 CORS 액세스를 허용하는 것은 권장되지 않습니다.
  • HTTPS 사용: 가능할 경우, 데이터가 암호화되지 않은 형태로 노출될 수 있으므로 CORS 구성에서 비-HTTPS 사이트를 허용하는 것을 피하세요.
2개의 좋아요

그리고 구글 광고를 사용 중이라면 이 설정에 손을 대지 않는 것이 더 나을 수 있습니다 :wink:

CORS(그리고 CSP)는 다소 문제적인 부분이 있는데, 실제로는 사이트가 거의 모든 것을 허용해야 하는 경우가 많기 때문에 그렇게 되면 사실상 무용지물이 되기 때문입니다.

2개의 좋아요

사이트의 app.yml 파일 env 섹션에 DISCOURSE_ENABLE_CORS: "true"를 추가했습니다.
그 후 앱을 다시 빌드했습니다.
이어서 cors_origins 섹션으로 가서 상호작용을 시도하는 사이트의 전체 URL을 추가했지만 여전히 작동하지 않습니다.
메인 사이트가 오프라인일 때 정보를 제공하기 위한 페이지를 생성했습니다.
이 페이지에 메인 사이트 상태를 확인하고, 복구되면 해당 사이트로 리다이렉트하기 위한 다음 JS를 넣었지만 작동하지 않는 것 같습니다.
코드는 다음과 같습니다:

    <script>
        function checkSiteStatus() {
            fetch('https://discourse.technospider.com', {
                method: 'HEAD',
                mode: 'cors', // Use CORS to get status code
                cache: 'no-store' // Avoid caching
            })
            .then(response => {
                console.log('Site check: Status', response.status);
                if (response.ok) { // 200-299 status codes
                    console.log('Site is up, redirecting to Discourse');
                    window.location.replace('https://discourse.technospider.com');
                } else {
                    console.log('Site is still down (status: ' + response.status + '), retrying in 20 seconds');
                    setTimeout(checkSiteStatus, 20000);
                }
            })
            .catch(error => {
                console.log('Site check: Error (likely down or CORS issue):', error.message);
                setTimeout(checkSiteStatus, 20000);
            });
        }
            
        // Start checking immediately
        checkSiteStatus();
    </script>

그리고 콘솔 오류는 다음과 같습니다:

[Error] Origin https://www.technospider.com is not allowed by Access-Control-Allow-Origin. Status code: 200
[Error] Fetch API cannot load https://discourse.technospider.com/ due to access control checks.
[Error] Failed to load resource: Origin https://www.technospider.com is not allowed by Access-Control-Allow-Origin. Status code: 200 (discourse.technospider.com, line 0)
[Log] Site check: Error (likely down or CORS issue): – "Load failed" (berightback, line 78)
```\n혹시 통찰이 있으신 분이 계시다면 알려주시면 좋겠습니다. Grok과 저는 막막합니다.

이중 따옴표를 제거하고 시도해 보세요. 그렇지 않으면 불리언 값이 아닌 문자열로 해석될 수 있습니다.

지금 재구성이 완료될 때까지 기다리며 테스트하고 있습니다. 만약 그게 사실이라면, 누군가가 이 페이지를 수정해야 합니다:

이 페이지에는 true를 이중 인용부호 안에 넣도록 안내하고 있기 때문입니다.

재구성 완료, 변경 사항 없음. :frowning:

글쎄, 그건 좀 이상하네… 다른 환경 변수들은 따옴표 없이 true 값이 들어 있거든.

예를 들어 게시글에서 JavaScript를 사용하려면 CSP보다 이 방식이 더 나은가요?

현재 저는 JavaScript를 실행하기 위해 테마 컴포넌트나 CSP에 의존하고 있습니다.

감사합니다.
올레

여기서는 환경 변수로 들어가는데, 환경 변수는 문자열만 가능합니다. 그래서 상관없습니다.

하지만 일반적으로는 이런 점을 주의할 필요가 있습니다. 무해해 보이는 값에서 의도하지 않은 결과가 나올 수 있기 때문입니다:

pry(main)> YAML.load('on: yes').to_s
=> "{true=>true}"
1개의 좋아요

안녕하세요! 제가 통제하지 않는 잠재적으로 위험한 웹사이트에서 /latest.json을 로드하고 싶습니다. /latest.json과 같은 특정 URL에 대해서만 CORS 헤더를 활성화하고, 예를 들어 /u/myname/user-menu-private-messages에는 활성화하지 않는 것이 가능한가요?