며칠 전, 포럼 회원들이 제공한 외부 링크로부터 내 웹사이트를 보호하는 전략을 찾고 있었습니다. 유해 URL에 대한 자체 데이터베이스를 구축해 보려 했지만, 생각보다 훨씬 어려웠습니다. 링크의 양이 워낙 방대해서 분류하기가 쉽지 않았죠. 그래서 제 요구사항에 맞는 API 서비스를 찾아보다가 구글이 제공하는 무료 서비스인 Google Safe Browsing API를 발견했고, 이를 Discourse 포럼에 추가해 보기로 했습니다.
제 포럼에서의 결과
*마우스를 올렸을 때
다음과 같이 진행했습니다.
Discourse에서 모든 외부 링크 뒤에 아이콘을 추가하고, Google Safe Browsing Lookup API(v4)를 사용하여 링크의 보안 상태를 표시하는 툴팁을 보이려면 다음 단계를 따르세요:
-
Google Safe Browsing용 API 키 생성:
- Google Cloud Console로 이동하세요.
- 새 프로젝트를 생성하거나 기존 프로젝트를 사용하세요.
- Safe Browsing API를 활성화하세요.
- 해당 프로젝트에 대한 API 키를 생성하세요.
*모든 것이 무료입니다.
-
Discourse 관리자 로그인:
- 관리자 계정으로 Discourse에 로그인하세요.
-
테마 사용자 정의 접근:
- “관리자” → “사용자 정의” → "테마"로 이동하세요.
- 편집할 테마를 선택하거나 새 테마 또는 테마 구성 요소를 생성하세요.
-
CSS 추가:
-
원하는 테마의 "CSS/HTML 편집"을 클릭하세요.
-
“CSS” 탭에 다음 코드를 추가하세요:
a[target="_blank"]:after { content: url('https://example.com/icon.png'); /* 원하는 아이콘의 URL로 교체하세요 */ margin-left: 5px; /* 링크와 아이콘 사이의 간격 */ display: inline-block; } .tooltip { position: relative; display: inline-block; } .tooltip .tooltiptext { visibility: hidden; width: 200px; background-color: #555; color: #fff; text-align: center; border-radius: 6px; padding: 5px; position: absolute; z-index: 1; bottom: 125%; /* 툴팁 위치 */ left: 50%; margin-left: -100px; opacity: 0; transition: opacity 0.3s; } .tooltip:hover .tooltiptext { visibility: visible; opacity: 1; }
-
-
JavaScript 추가:
-
테마의 “Header” 탭에 다음 코드를 추가하세요:
<script type="text/discourse-plugin" version="0.8"> api.onPageChange(() => { const externalLinks = document.querySelectorAll('a[href^="http"]:not([href*="' + window.location.hostname + '"])'); const apiKey = 'YOUR_GOOGLE_API_KEY'; // API 키로 교체하세요 const lookupUrl = 'https://safebrowsing.googleapis.com/v4/threatMatches:find?key=' + apiKey; externalLinks.forEach(link => { link.setAttribute('target', '_blank'); link.classList.add('tooltip'); const tooltipText = document.createElement('span'); tooltipText.className = 'tooltiptext'; tooltipText.innerText = '링크 안전성 확인 중...'; link.appendChild(tooltipText); fetch(lookupUrl, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ client: { clientId: 'yourcompany', clientVersion: '1.5.2' }, threatInfo: { threatTypes: ['MALWARE', 'SOCIAL_ENGINEERING'], platformTypes: ['ANY_PLATFORM'], threatEntryTypes: ['URL'], threatEntries: [ { url: link.href } ] } }) }) .then(response => response.json()) .then(data => { if (data.matches && data.matches.length > 0) { tooltipText.innerText = '경고: 이 링크가 안전하지 않을 수 있습니다!'; tooltipText.style.backgroundColor = '#ff0000'; } else { tooltipText.innerText = '이 링크는 안전합니다.'; } }) .catch(error => { tooltipText.innerText = '링크 안전성 확인 중 오류가 발생했습니다.'; }); }); }); </script>이 JavaScript는 다음을 수행합니다:
- 모든 외부 링크를 찾아 새 탭에서 열리도록 설정합니다.
- 링크 뒤에 아이콘을 추가합니다.
- Google Safe Browsing API를 사용하여 링크를 확인하고 결과를 툴팁에 표시합니다.
-
-
테마 저장 및 적용:
- 변경 사항을 저장하려면 "저장"을 클릭하세요.
- 새 테마를 생성한 경우 기본 테마로 설정하거나 원하는 사용자 그룹에 할당하세요.
이 단계를 따르면 Discourse 인스턴스의 모든 외부 링크 뒤에 아이콘이 표시되고, Google Safe Browsing API를 사용하여 링크의 보안 상태를 보여주는 툴팁이 나타납니다.
보안을 위한 수정 사항
Google API 사용에 대한 웹사이트 제한(Website limits) 섹션에 웹사이트를 추가해야 합니다.
옵션
Font Awesome 아이콘 사용
Font Awesome 아이콘을 사용하려면 아래는 업데이트된 CSS입니다:
Font Awesome 아이콘이 포함된 업데이트된 CSS
/* Font Awesome이 포함되었는지 확인 */
@import url('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css');
/* 외부 링크 뒤에 Font Awesome 아이콘 추가 */
a[target="_blank"]:after {
content: "\f35d"; /* Font Awesome 외부 링크 아이콘의 유니코드 */
font-family: 'Font Awesome 5 Free'; /* Font Awesome 패밀리 */
font-weight: 900; /* Font Awesome 솔리드 가중치 */
margin-left: 5px; /* 링크와 아이콘 사이의 간격 */
display: inline-block;
}
설명:
-
Font Awesome 가져오기:
- CSS는 CDN에서 Font Awesome CSS를 가져오는 것으로 시작합니다.
-
아이콘 추가:
a[target="_blank"]:after선택자의content속성은 Font Awesome 외부 링크 아이콘의 유니코드인"\f35d"로 설정됩니다.font-family는 'Font Awesome 5 Free’로,font-weight는 아이콘의 솔리드 버전을 사용하기 위해900으로 설정됩니다.
이 글이 저와 같은 것을 찾고 있는 분들에게 도움이 되기를 바랍니다.


