Discourse 임베딩을 통해 특정 페이지와 연결된 토픽 ID나 Discourse URL을 찾는 방법이 있을까요? 임베딩된 댓글이 포함된 페이지에 포함하는 schema.org discussionUrl JSON-LD에 Discourse URL을 제공하려고 합니다. 예를 들어,
스크립트가 호출될 때마다 고유한 div id를 전달하는 방법이 있을까요? 메인 기사 아래에 비동기 방식으로 콘텐츠를 로드하고 있으며, 해당 항목에도 댓글이 표시되기를 원합니다. 물론 현재 설정의 문제는 모든 댓글이 ‘discourse-comments’ div id에 표시된다는 점입니다.
조만간 이 기능을 사용해보고 싶은데, 저희 웹사이트에는 30,000개 이상의 블로그가 있습니다. 댓글이 없는 모든 블로그가 포럼에 표시되길 원하지 않습니다. 블로그가 OnLoad 시점에 토픽으로 삽입되기 때문에, 방문할 때(예: 구글을 통해) 모든 블로그가 삽입되지 않도록, 임베드에서 버튼을 클릭한 후에야 포럼에 삽입되도록 할 수 있는 방법이 있는지 궁금합니다.
새로운 토픽 개요 페이지가 블로그로 넘쳐날 것 같습니다 (일반적인 정식 사용자에게는 처음부터 비공개로 시작하므로 관리자 입장에서 특히 그렇습니다).
Disqus의 블로그 댓글을 Discourse 포럼으로 마이그레이션하기 위해 몇 가지 스크립트를 작성했습니다. 이 과정에서 Discourse API를 사용해 주제를 직접 생성했으며, 이 통합 플러그인이 생성하도록 두지 않았습니다. 기존 게시물에는 topicId 임베딩 방식을 사용하고 있으며, 앞으로의 새 게시물에는 discourseEmbedUrl 방식을 사용하고 있습니다.
하지만 일부 새 주제가 여전히 생성되는 이상한 문제가 발생하고 있습니다. (일부 게시물에서 topicId가 잠시 누락되었을 때 제 코드에 버그가 있었기 때문으로 추정되며, 해당 게시물들이 중복으로 생성되고 있는 것으로 보입니다.) 현재 제가 해결할 방법은 없다고 생각하지만, 향후를 위한 해결책을 제안하고자 합니다.
임베드 컨트롤러가 기존 게시물을 embed_url 데이터베이스 컬럼으로 조회하려고 시도하고 있으므로, 주제를 생성할 때 해당 필드를 설정할 수 있는 API 속성을 추가해 주었으면 합니다. 이렇게 하면 제 임포트 스크립트가 해당 주제의 이 속성을 설정할 수 있게 됩니다. 그러면 이 통합 플러그인은 JS에서 topicId와 discourseEmbedUrl 필드 간 전환을 걱정할 필요가 전혀 없게 될 것입니다.
임베드 플러그인 관련 문제의 원인을 찾았습니다. 임베드를 설정할 때 “허용된 호스트”(Allowed Hosts) 설정이 있으며, 이 설정은 iframe의 CSP(Content Security Policy)를 설정합니다. 따라서 iframe은 해당 호스트에서만 표시됩니다. 예를 들어, 허용된 호스트를 example.com으로 설정한 후 attacker.com에서 JS를 임베드하려고 하면, iframe이 로드되는 것이 거부되고 다음과 같은 오류가 발생합니다.
Refused to frame 'https://forum.example.com/' because an ancestor violates the following Content Security Policy directive: "frame-ancestors 'self' https://example.com".
그러나 이 시점에서는 JS가 이미 실행되어 임베드 코드에 주어진 URL로 포럼에 토픽을 생성해 버립니다.
제 경우의 상황은 Netlify를 사용하여 빌드를 미리 보기 때문에 블로그의 사본이 실제로 netlify.app URL에서 제공되고, 이 환경에서 해당 embed.js가 로드되어 이전에 잘못 가져온 게시물을 위한 포럼 스레드를 생성하고 있는 것입니다.
이것은 반드시 보안 문제는 아닙니다. 설정된 웹사이트 URL 중 경로 허용 목록(path allowlist)과 일치하는 URL에 대해서만 토픽을 생성할 수 있기 때문입니다. 하지만 이전 게시물을 Discourse로 이관하는 과정에서 포럼 스레드에 embed_url을 설정할 방법이 없었기 때문에, 이 마이그레이션 전략에서는 문제가 됩니다.
해결 방법은 “허용된 호스트” 설정에 포함되지 않은 도메인에서 embed.js가 실행되는 것을 방지하기 위해 CSP 규칙을 추가하는 것입니다.
개념 증명(Proof of Concept)으로, 임베드 코드를 완전히 무관한 도메인에 복사하고 discourseEmbedUrl을 이전에 가져온 오래된 게시물 중 하나로 설정했습니다. 페이지를 로드했을 때 iframe은 차단되었지만, JS는 이미 실행되어 포럼 스레드를 생성해 버렸습니다.
이것이 버그보다는 보안 문제로 판단된다면, 이 게시물을 삭제하고 대신 HackerOne을 통해 보고하는 것을 기꺼이 수행하겠습니다.