Wie man Disqus Kommentarbereiche absichert


Dieser Beitrag zeigt, wie die Hexis API in das Disqus-Diskussionssystem integriert werden kann. Sie können beleidigende Nachrichten automatisch erkennen, blockieren und den Autoren eine Fehlermeldung anzeigen – alles innerhalb von Millisekunden.

Disqus ist ein weit verbreiteter Dienst für die Kommentierung von Blogs und Nachrichtenseiten, aber auch allgemein für statische HTML-Seiten, da er es ermöglicht, sehr einfach eine Kommentarfunktion zu integrieren. Dennoch wollen wir etwas Leistungsfähigeres als den eingebauten Toxizitätsfilter verwenden. Im Folgenden wird gezeigt, wie man die Integration mit Hexis API vornimmt und jeden Kommentar, der über Disqus gepostet wird, automatisch überprüfen lassen kann.

Hinweis: Wenn Sie noch keinen Hexis API-Schlüssel haben, gehen Sie zu Ihrem Konto und erstellen Sie kostenlos einen. Außerdem müssen Sie sich für die Disqus API registrieren.

Unsere Integration kann durch einen Callback implementiert werden, wie in der Disqus-Dokumentation gezeigt wird. Im folgenden Standard-Einbettungscode

var disqus_shortname = '<example>';  // Required - Replace example with your forum shortname

(function() {
  var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
  dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
  (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
})();

kann eine Funktion definiert werden, die für jeden neuen Kommentar ausgelöst wird. Alles was dafür benötigt wird, ist den Hexis API Client-Code in einen onNewComment-Callback einzubinden und diesen dem Standard-Einbettungscode hinzuzufügen.

Wir können dies auf der Client-Seite implementieren und dabei nur Vanilla-Javascript verwenden (keine Frameworks erforderlich).

var disqus_config = function() {

  this.callbacks.onNewComment = [function(comment) {
    var HEXIS_URL = 'https://api.hexis.ai/mod-1/de';
    var HEXIS_KEY = 'Ihr Hexis API-Schlüssel';
    var THRESHOLD = 0.9;
    var DISQUS_URL = 'https://disqus.com/api/3.0/posts/remove.json';
    var DISQUS_KEY = 'Ihr Disqus API-Schlüssel';
    var STOP_MESSAGE = 'Bitte formulieren Sie Ihren Kommentar neu. Es sieht so aus, als würde Ihr Kommentar wahrscheinlich als unhöflich oder respektlos interpretiert werden.';
    var ERROR_MESSAGE = 'Es ist ein Fehler aufgetreten. Bitte versuchen Sie es erneut.';

    var data = JSON.stringify({'text': comment.text});
    var xhr = new XMLHttpRequest();
    xhr.open('POST', HEXIS_URL, true);
    xhr.setRequestHeader('Authorization', 'Bearer '+HEXIS_KEY);
    xhr.onload = function () {
      var res = JSON.parse(this.response);
      if (res.scores != null) {
        if (res.scores[0] > THRESHOLD) {
          alert(STOP_MESSAGE);

          var data2 = JSON.stringify({'api_key': DISQUS_KEY, 'post': comment.id});
          var xhr2 = new XMLHttpRequest();
          xhr2.open('POST', DISQUS_URL, true);
          xhr2.onload = function () {
            var res2 = JSON.parse(this.response);
            if (res2.code != 0) {
              alert(ERROR_MESSAGE);
        }
      } else {
        alert(ERROR_MESSAGE);
      }
    };
    xhr.send(data);
  }];

};

Geben Sie Ihre API-Schlüssel am Anfang dieser Funktion als HEXIS_KEY und DISQUS_KEY an.

Der THRESHOLD Wert ist mit 0.9 relativ hoch angesetzt. Das liegt daran, dass wir in dem gegebenen Beispiel jede Nachricht, die diesen Wert überschreitet, nicht überprüfen, sondern sofort zurückweisen werden, so dass wir wahrscheinlich nicht wollen, dass sie übermäßig empfindlich ist. Natürlich kann dieser Wert abhängig von Ihrem Anwendungsfall eingestellt werden. Weitere Informationen finden Sie in der Hexis Dokumentation.

Anstatt Kommentare sofort zu verwerfen, ist es auch möglich, DISQUS_URL auf https://disqus.com/api/3.0/posts/report.json zu setzen. Die Kommentare werden dadurch gekennzeichnet und können manuell moderiert werden.

Dieser Ansatz impliziert, dass die API-Schlüssel im Quellcode Ihrer Webseite aufscheinen – was für kleinere Anwendungsfälle an sich kein Problem darstellt. Der API-Zugriff muss jedoch mit Hilfe der Client-Einschränkungen auf Ihrer Kontoseite beschränkt und nur Ihre Webseite zugelassen werden.

Geben Sie die vollständige URL-Adresse Ihrer Webseite (einschließlich http://) in das Feld Allow Referrer URL ein.

Testen Sie den Schutz Ihres Eingabeformulars und die folgende Fehlermeldung wird angezeigt.

Gut gemacht, es kommen keine schädlichen Nachrichten mehr durch Ihre Disqus-Kommentare!

Mehr Sicherheit

Ergänzend zu der oben gezeigten Integration ist es möglich, die Funktionalität zwischen der Client- und der Server-Seite aufzuteilen. Dies hat den Vorteil, dass Verbindungsdetails wie der API-Schlüssel ausgeblendet werden können und die Sicherheit nicht nur auf referrer-basierter Zugriffskontrolle beruht. Wenn Sie nicht selbst eine Web-Applikation betreiben, ist der einfachste Weg dies zu erreichen über ein kurzes PHP-Skript – siehe den Beitrag: Wie man jede Art von Eingabeformular absichert.

Der komplette Embed-Code für Ihr HTML-Template:

<div id="disqus_thread"></div>
<script>

    var disqus_config = function() {
      this.page.identifier = '{{ article.url }}';
      this.page.url = '{{ SITEURL }}/{{ article.url }}';
      this.callbacks.onNewComment = [function(comment) {
        var PHP_URL = 'api.php';
        var STOP_MESSAGE = 'Please rephrase your comment. It looks like your comment is likely to be interpreted as rude or disrespectful.';
        var data = new FormData();
        data.append('text', comment.text);
        data.append('id', comment.id);
        var xhr = new XMLHttpRequest();
        xhr.open('POST', PHP_URL, true);
        xhr.onload = function () {
          var res = JSON.parse(this.response);
          if (res.status == 1) {
            alert(STOP_MESSAGE);
          }
        };
        xhr.send(data);
      }];
    };

    (function() {
        var d = document, s = d.createElement('script');
        s.src = 'https://{{ DISQUS_SITENAME }}.disqus.com/embed.js';
        s.setAttribute('data-timestamp', +new Date());
        (d.head || d.body).appendChild(s);
    })();
</script>
<noscript>
    Please enable JavaScript to view the 
    <a href="https://disqus.com/?ref_noscript" rel="nofollow">
        comments powered by Disqus.
    </a>
</noscript>

Das komplette api.php Skript:

<?php

$HEXIS_KEY = '';
$DISQUS_KEY = '';
$DISQUS_TOKEN = '';
$THRESHOLD = 0.9;

function classify ($text) {
  global $HEXIS_KEY;
  $postData = json_encode(array('text' => $text));
  $ch = curl_init('https://api.hexis.ai/mod-1/en');
  curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
  curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Bearer '.$HEXIS_KEY, 'Content-Length: '.strlen($postData)));
  curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  $response = curl_exec($ch);
  curl_close($ch);
  return $response;
}

function remove ($id) {
  global $DISQUS_KEY, $DISQUS_TOKEN;

  $getThreadDetails = 'https://disqus.com/api/3.0/posts/remove?api_secret='.$DISQUS_KEY.'&post='.$id.'&access_token='.$DISQUS_TOKEN;
  $threadDetailsSession = curl_init($getThreadDetails);
  curl_setopt($threadDetailsSession,CURLOPT_POST, true);
  curl_setopt($threadDetailsSession,CURLOPT_POSTFIELDS, '');
  curl_setopt($threadDetailsSession,CURLOPT_RETURNTRANSFER, true);
  $response = curl_exec($threadDetailsSession);
  curl_close($threadDetailsSession);
}

if ($_POST['text'] != '' and $_POST['id'] != '' and $_SERVER['HTTP_ACCEPT_LANGUAGE'] != '' and strpos($_SERVER['CONTENT_TYPE'], 'multipart/form-data') !== false) {
  $result = json_decode(classify($_POST['text']));
  if ($result->scores[0] >= $THRESHOLD) {
    remove($_POST['id']);
    echo json_encode(array('status' => 1));
  } else {
    echo json_encode(array('status' => 0));
  }
}

?>