Blog 4 Umbraco 2.0.8 - Kommentar-Spammer abwehren

Dienstag, 8. Dezember 2009 von Immo Wache
Kategorien: Umbraco  Blog  deutsch  Weihnachtskalender 

Original von Tim Geyssens

Im heutigen Kapitel (Hinweis: Es trägt die Version 2.0.8 - das gestrige Kapitel sollte damit eigentlich 2.0.7 gewesen sein - kleiner Patzer der Weihnachtselfen) wird das Blog für Umbraco um einen verbesserten Spam-Schutz erweitert. Wir werden eine Prüfung der Kommentare mit Hilfe des Akismet Spam-Filter-Service realisieren. Da Akismet nicht der einzig verfügbare Spam-Filter-Service ist werden wir ein einfaches Provider-Modell erstellen. Das machte es uns dann später einfacher, wenn wir einen anderen Service Provider hinzuzufügen und verwenden möchten.

Bevor wir Akismet benutzen können, benötigen wir einen gültigen API-Schlüssel. Wir können einen Schlüssel kostenlos erhalten wenn wir bei Akismet ein Benutzerkonto anlegen (http://akismet.com/personal/). Dieser API-Schlüssel muss als Wert in der "Blog für Umbraco" Installation verfügbar sein. Er wird dafür einfach im Blog-Dokument unter dem Reiter Akismet eingetragen. Daher müssen wir im zugehörigen Blog-Dokumenttyp ein entsprechendes Eigenschaftsfeld anlegen:

image_1

Nachdem die neue Eigenschaft eingefügt ist, können wir den API-Schlüssel im Blog-Dokument eintragen:

image_2

Damit sind wir nun gut vorbereitet, den Akismet Spamschutz zu benutzen. Wir beginnen damit, ein einfaches Provider-Modell einzurichten. Spam-Filter-Dienste funktionieren so, dass wir sie mit den kompletten neuen Kommentar-Daten füttern, der Dienst diese Daten dann überprüft und uns zurück liefert, ob der Kommentar als Spam zu bewerten ist oder nicht.

Somit definieren wir ein Interface, welches eine Check-Methode mit allen Kommentar-Informationen enthält (Browser-Typ, IP-Adresse, Autor, E-Mail des Autors, seine URL und natürlich der eigentliche Kommentar):

    public interface ISpamChecker
    {
        String ProviderName { get; set; }

        Boolean Check(int nodeid,
            string UserAgent, string UserIp, string Author,
            string AuthorEmail, string AuthorUrl, string Content);
    }

Als nächstes fügen wir eine abstrakte Klasse hinzu, die dieses neue Interface implementiert:

    public abstract class SpamChecker: ISpamChecker
    {
        #region ISpamChecker Members

        private string m_providername;
        public string ProviderName
        {
            get { return m_providername; }
            set { m_providername = value; }
        }

        public virtual bool Check(
            int nodeid, string UserAgent, string UserIp,
            string Author, string AuthorEmail, string AuthorUrl, string Content)
        {
            return false;
        }

        #endregion
    }

Anschließend fügen wir die eigentliche Akismet SpamChecker - Klasse ein, die natürlich von unserer abstrakten Klasse abgeleitet wird und die Check-Methode überschreibt. Es gibt bereits einen Open-Source .net Wrapper für den Akismet Service (http://www.codeplex.com/AkismetApi), daher erfinden wir hier das Rad nicht noch einmal sondern benutzen ihn einfach:

public class AkismetSpamChecker: SpamChecker   {

       public AkismetSpamChecker()
       {
           this.ProviderName = "Akismet";
       }

       public override Boolean Check(int nodeid,
           string UserAgent, string UserIp, string Author,
           string AuthorEmail, string AuthorUrl, string Content)
       {

           umbraco.presentation.nodeFactory.Node blog =
               new umbraco.presentation.nodeFactory.Node(nodeid);

           while (blog.NodeTypeAlias != "Blog")
           {
               blog = blog.Parent;
           }

           if (blog.GetProperty("akismetAPIKey").Value != string.Empty)
           {               
                Akismet api = new Joel.Net.Akismet(
                   blog.GetProperty("akismetAPIKey").Value,
                   "http://" + HttpContext.Current.Request.ServerVariables["HTTP_HOST"] + blog.Url,
                   "Blog4Umbraco2");

               if (!api.VerifyKey())
               {
                   umbraco.BusinessLogic.Log.Add(
                       umbraco.BusinessLogic.LogTypes.Error,
                       -1,
                       "Akismet Key could not be verified, please check if you have a valid Akismet API Key");

                   return false;
               };

               AkismetComment comment = new AkismetComment();
               comment.UserAgent = UserAgent;
               comment.UserIp = UserIp;
               comment.CommentType = "comment";
               comment.CommentAuthor = Author;
               comment.CommentAuthorEmail = AuthorEmail;
               comment.CommentAuthorUrl = AuthorUrl;
               comment.CommentContent = Content;

               return api.CommentCheck(comment);
           }
           else
           {
               return false;
           }
       }
}

In der Methode Check suchen und überprüfen wir zunächst, ob ein gültiger API-Schlüssel verfügbar ist (unter Verwendung der Umbraco NodeFactory finden wir das Blog-Dokument). Wenn alles soweit korrekt ist, liefern wir einfach das Ergebnis der Kommentarprüfung über den Web-Service als Ergebnis zurück.

Der letzte Schritt besteht nun im eigentlichen Aufruf dieser Check-Methode wenn ein neuer Kommentar zugesendet wird. Da wir es ja ermöglichen wollen, dass wir später einen anderen bzw. auch einen eigenen Spam-Prüfer einhängen, fügen wir dazu noch eine kleine Konfigurationsdatei hinzu:

<?xml version="1.0"?>
<SpamChecker assembly="/bin/Umlaut.Umb.Blog" type="Umlaut.Umb.Blog.Spam.AkismetSpamChecker">
</SpamChecker>

Diese Konfigurationsdatei enthält die Assembly und den Typ der Spam Prüfer - Klasse die verwendet werden soll (als Vorgabe hier natürlich unsere neue Akismet Klasse). Mit Hilfe von Reflection rufen wir die Check-Methode des gewünschten Klassen-Typs auf den wir über die Konfigurationsdatei ermitteln:

           bool isspam = false;

           try
           {
               string assemblyFile =
                   HttpContext.Current.Server.MapPath(
                   String.Format("{0}/..{1}.dll",
                   GlobalSettings.Path,
                   Config.GetProviderAssembly()));

               Assembly checkerAssembly = Assembly.LoadFrom(assemblyFile);

               SpamChecker checker =
                   (SpamChecker)Activator.CreateInstance(
                   checkerAssembly.GetType(Config.GetProviderType()));

               isspam = checker.Check(parentId,
                   post.UserAgent, post.UserHostAddress,
                   name, email, website, comment);
           }
           catch (Exception ex) { }

Wir müssen nur noch unsere gestrige Anweisung zum Einfügen eines Kommentars aktualisieren, damit nicht immer false sondern der ermittelte Wert isspam einfügt wird.

Das war's, unsere zugesendeten neuen Kommentare werden nun von Akismet gecheckt, und wenn sie als Spam angesehen werden, so erscheinen sie nicht mehr auf unserem Blog (da ja Kommentare, die als Spam markiert sind, nicht im Frontend dargestellt werden).

4 Kommentar(e) zu “Blog 4 Umbraco 2.0.8 - Kommentar-Spammer abwehren”

  1. Keisha schrieb:
    AFAICT you've covered all the bases with this awnser!
  2. bnrbhhsenpo schrieb:
    NF4bgt , [url=http://zlyozqebubmm.com/]zlyozqebubmm[/url], [link=http://hutbhklzlbmb.com/]hutbhklzlbmb[/link], http://dotafvqbsbsq.com/
  3. qzhdrckdtn schrieb:
    4EmMwa , [url=http://gygfvmenbkxw.com/]gygfvmenbkxw[/url], [link=http://yzyvzhcjvees.com/]yzyvzhcjvees[/link], http://gmlywluzefij.com/
  4. Storm schrieb:
    I feel so much happier now I unedsrtand all this. Thanks!

Beitrag kommentieren:


wird nicht angezeigt


optional - bitte mit http://



Bitte geben Sie den im darüberliegenden Bild erkennbaren Sicherheitscode ein, um einen SPAM-Missbrauch des Formulars zu verhindern.