서브폴더 사용 시 svg-sprite에서 발생하는 Discourse_docker (blocked:csp) 오류

https://sales-community-staging.rainmakers.co/sales-community/ 를 방문하여 문제를 확인해 보세요. 영구적으로 유지된다는 보장은 없습니다.
URL에 /sales-community를 추가하지 않기 때문이라고 생각합니다.
app.yml 또는 nginx.conf를 제공하는 것이 도움이 될지 알려주세요.
이 문제는 version: tests-passed 버전에서 발생합니다.
수정하려고 version: stable을 시도해 보았지만, 현재 docker에서 컴파일이 되지 않습니다(이전에 본 다른 버그 보고서에서 언급된 내용이며, 저는 새로 시작하는 중이지 다운그레이드하는 것이 아닙니다).

여러 장의 이미지를 게시할 수 있는 기능을 제공해 주실 수 있나요? :slight_smile:

1개의 좋아요

서브폴더의 howto 문서를 따랐나요?

네. 그 외에는 모두 정상적으로 작동합니다(게시물 작성, 이메일, 아바타 업로드, https 등). 다른 모든 리소스는 적절한 /sales-community 서브폴더 URL을 사용하고 있습니다(이미지 참조). SVG만 깨져 있습니다.

# app.yml

stuff...

DISCOURSE_HOSTNAME: sales-community.rainmakers.co
DISCOURSE_RELATIVE_URL_ROOT: /sales-community

stuff...

run:
    - exec:
        cd: $home
        cmd:
          - mkdir -p public/sales-community
          - cd public/sales-community && ln -s ../uploads && ln -s ../backups
    - replace:
       global: true
       filename: /etc/nginx/conf.d/discourse.conf
       from: proxy_pass http://discourse;
       to: |
          rewrite ^/(.*)$ /sales-community/$1 break;
          proxy_pass http://discourse;
    - replace:
       filename: /etc/nginx/conf.d/discourse.conf
       from: etag off;
       to: |
          etag off;
          location /sales-community {
             rewrite ^/sales-community/?(.*)$ /$1;
          }
    - replace:
         filename: /etc/nginx/conf.d/discourse.conf
         from: $proxy_add_x_forwarded_for
         to: $http_your_original_ip_header
         global: true

네, 문제는 CSP가 아니라 URL 자체가 잘못된 것 같습니다. apparently 서브폴더 경로가 접두사로 붙지 않는 것 같고, 아마 여기에 추가해야 할 것 같습니다.

4개의 좋아요

음, 이건 서브폴더 버그인가요 @eviltrout?

서브폴더 시나리오에서 SVG 스프라이트를 처리하는 로직은 이미 모두 갖춰져 있으며, 여러 사이트에서 성공적으로 사용되고 있습니다. 이번 경우에는 매우 구체적인 엣지 케이스에 부딪힌 것입니다. @vkozyrev의 사이트에서 주요 변수들을 확인해 보겠습니다(브라우저 콘솔에서).

> Discourse.SvgSpritePath
"/svg-sprite/sales-community-staging.rainmakers.co/svg-2-8ed106e6e3d908b1b86898dfe93a7bac0fd358f4.js"
> Discourse.BaseUri
"/sales-community"

문제없어 보입니다. 이제 SVG 스프라이트 시트를 로드할 때 loadScript를 사용하는데, 이는 다시 Discourse.getURL을 호출합니다. 이 함수는 서브폴더 접두사를 추가하는 역할을 합니다. 직접 테스트해 보겠습니다:

> Discourse.getURL(Discourse.SvgSpritePath)
"/svg-sprite/sales-community-staging.rainmakers.co/svg-2-8ed106e6e3d908b1b86898dfe93a7bac0fd358f4.js"

음… 아무것도 일어나지 않았습니다. 다른 랜덤 URL은 잘 동작합니다:

> Discourse.getURL("/blah")
"/sales-community/blah"

조금 더 파고들면 getUrl 내부의 이 라인을 찾을 수 있습니다.

if (url.indexOf(Discourse.BaseUri) !== -1) return url;

즉, 영어로 "URL에 이미 서브폴더 접두사가 포함되어 있으면 포기한다"는 의미입니다. 따라서 여기의 문제는 @vkozyrev의 서브폴더 접두사(/sales-community)가 SVG 스프라이트 시트 URL의 중간에 포함되어 있다는 점입니다.

/svg-sprite/sales-community-staging.rainmakers.co/svg-2-8ed106e6e3d908b1b86898dfe93a7bac0fd358f4.js

이 검사를 더 구체적으로 변경하여, URL의 시작 부분에서만 서브폴더 접두사를 확인하도록 했습니다:

다만, 이로 인해 다른 잠재적인 문제들도 생각납니다… 예를 들어, 누군가가 서브폴더 접두사로 /t나 /about 또는 Discourse에서 사용하는 다른 URL을 원한다면 어떻게 될까요 :thinking:

10개의 좋아요

@vkozyrev 이제 병합되었으니, 사이트를 업데이트해 보시고 문제가 해결되었는지 알려주세요 :slight_smile:

@david 님, 문제가 수정되었습니다.

정말 놀라운 엣지 케이스네요 :smiley:. 저는 Rails(API 모드 전용) 개발을 하고 있어서, 토끼굴에 너무 깊이 빠지지 않아서 다행입니다. 그랬으면 클라이언트 코드에서 길을 잃었을 거예요.

궁금해하시는 분들을 위해 말씀드리면, 이 서비스 앞에 프록시를 두고 있어서 sales-community 서브도메인은 사용자들에게 노출되지 않습니다. 사용자는 메인 사이트 URL 앞에 /sales-community만 보게 됩니다. 메인 사이트는 Heroku에 호스팅되어 있어서 단일 nginx 인스턴스로 모든 라우팅을 처리할 수 없거든요.

빠른 답변과 수정에 감사드립니다!

6개의 좋아요