Posts mit dem Label reCaptcha werden angezeigt. Alle Posts anzeigen
Posts mit dem Label reCaptcha werden angezeigt. Alle Posts anzeigen

Montag, 27. Juli 2020

ASP.net WebForms und "Googles" ReCaptcha

Nach verschiedenen Ausflügen in andere Bereiche meines Berufes (Desktop-, Mobile, IoT und reine HTML-Entwicklung) bin ich wieder bei einem Lieblinge angekommen den WebForms in ASP.net. Dort habe ich schon verschiedentlich "Captchas" eingebaut, auch das "ReCaptcha" von "Google", allerdings die Version 1.0, die nicht mehr unterstütz wird. Da gab es eine kleine DLL, die einem die meiste Arbeit abnahm, auf die wollte und konnte ich mich jetzt nicht verlassen.

Also habe ich ein wenig herumgesucht und bin, wie zumeist, bei "Stackoverflow" fündig geworden. Wie immer mußte man verschiedene Lösungsansätze zusammenbringen, um ein Ergebnis zu erzielen. Da es diesbezüglich Interesse zu geben scheint, will ich meinen Ansatz hier veröffentlichen.


Zunächst bauen wir den Zugriff auf die "Google-API" in den "Header" in der "Master.aspx" oder, wenn Ihr ohne "Master" arbeitet, in den Header der ".aspx"-Page ein, wo das "ReCaptcha" erscheinen soll:
Ich habe das so gelöst, daß ich in der "Master" einen "Content-Bereich für "JavaScript" in den Header geschrieben habe, benötige ich jetzt auf einer Seite spezielles "JavaScript", dann kann ich das auf den Pages bequem im Content plazieren. Dort kommt z.B. auch der HTML-Editor für die User rein, den benötige ich ja auch nicht auf allen Seiten.
Das sieht dann so aus:

Master.aspx

(...)
<html lang="en">
<head runat="server">
(...)
    <asp:ContentPlaceHolder ID="ScriptContent" runat="server">
    </asp:ContentPlaceHolder>
(...)
</head>
(...)


bei mir ist das die "Contact.aspx", da kommt rein:

(...)
<asp:Content ID="Content0" ContentPlaceHolderID="ScriptContent" runat="server">
(...)
    <script type="text/javascript" src="https://www.google.com/recaptcha/api.js" async            defer></script>
</asp:Content>
(...)


Ansonsten baut den Teil irgendwie in den "Header" ein:
<script type="text/javascript" src="https://www.google.com/recaptcha/api.js" async defer></script>

und anschließend den DIV-Tag, wo das ReCptcha-Widget gerendert werden soll:

<div id="dvCaptcha" class="g-recaptcha" data-sitekey="<%: ReCaptcha_Key %>"></div>


Den "ReCaptcha_Key" machen wir uns im Quellcode zugänglich (ich arbeite ausschließlich mit C#. solltet Ihr VB oder etwas ähnliches verwenden, müßt Ihr das leicht anpassen).

Bei mir heißt dann die "CodeBehind": Contact.aspx.cs und die startet mit:

{
    public partial class Contact : Page
    {
        (...)
        protected static string ReCaptcha_Key = "<RECaptcha Site Key>";

        protected static string ReCaptcha_Secret = "<RECaptcha Secret Key>";
(...)


Diese Declaration macht die Variabeln für das "ReCaptch" pagewide verfügbar und wir konnten den "ReCaptcha_Key" auf der "aspx" einfügen.

Jetzt müssen wir unserem "ReCaptcha" Leben einhauchen (Funktionalität geben), sonst sieht es zwar schön aus, wird aber keinen Einfluß auf die Validierung unseres Formulars haben. Da ich grundsätzlich alle Daten validiere, habe ich diese Funktion einfach um einen Methodeaufruf erweitert:

        protected void btnSendMessage_Click(object sender, EventArgs e)
        {
(...)
            try
            {
(...)
                if (!IsValidCaptcha()) throw new ValidationException("The ReCaptcha is wrong!");
(...)
            catch (Exception ex)
            {
                lblResult.Text = ex.Message;
                lblResult.ForeColor = System.Drawing.Color.Red;
            }
        }


Jetzt müssen wir nur noch das "ReCaptcha" validieren lassen:

        public bool IsValidCaptcha()
        {
            string resp = Request["g-recaptcha-response"];
            string quest = string.Format("https://www.google.com/recaptcha/api/siteverify?secret={0}&response={1}", ReCaptcha_Secret, resp);
            var req = (HttpWebRequest)WebRequest.Create
                      (quest);
            using (WebResponse wResponse = req.GetResponse())
            {
                using (StreamReader readStream = new StreamReader(wResponse.GetResponseStream()))
                {
                    string jsonResponse = readStream.ReadToEnd();
                    JavaScriptSerializer js = new JavaScriptSerializer();
                    // Deserialize Json
                    CaptchaResult data = js.Deserialize<CaptchaResult>(jsonResponse);
                    if (Convert.ToBoolean(data.success))
                    {
                        return true;
                    }
                }
            }
            return false;
        }
        public class CaptchaResult
        {
            public string success { get; set; }
        }


Da es jetzt haufenweise Fehlermeldungen hagelt, fügt bitte an entsprechender Stelle noch die "Using-Anweisungen" ein:

using System.Net;
using System.IO;
using System.Web.Script.Serialization;
using System.ComponentModel.DataAnnotations;


Hier noch einige Links, die Ihr ggf. brauchen könnt.

ReCaptcha Homepage: https://www.google.com/recaptcha/intro/v3.html

Falls Du schon einen Account bei Google hast, kommst Du hier zur richtigen Admin-Console:
https://www.google.com/recaptcha/admin/site/xxxxxxx

Und hier habe ich die Lösung ursprünglich gefunden:
https://stackoverflow.com/questions/27764692/validating-recaptcha-2-no-captcha-recaptcha-in-asp-nets-server-side

und ein herzliches Danke schön an Tabish Usman.





Montag, 17. August 2015

eMail-Adresse verbergen

Ich dachte eigentlich, daß dieses Thema zur Genüge im Netz dokumentiert sei. Deshalb haben mich die eMails, die mich ziemlich zahlreich erreicht haben, auch überrascht. Es geht darum die eMail-Adresse vor "Robots" zu verbergen, die nur dazu geschaffen wurden derlei Informationen auszuspähen und der werbenden Industrie zur Verfügung zu stellen. Das kann zu einer Flut von "Spam" führen.


Die Suchengines werden immer schlauer und selbst nur als Grafik hinterlegte Adressen werden gefunden. Das beste ist es also die Adresse überhaupt nicht preis zugeben. Das hat natürlich den Nachteil, daß der Besucher meiner Site seinen bevorzugten eMail-Client nicht verwenden kann und auf unser Formular angewiesen ist. Ich kenne genug Kunden, die dies ablehnen und lieber auf die Kontaktaufnahme verzichten.

Als Entwickler muß ich jedoch auch einen Ausweg aus dem Dilemma finden. Ich habe daher einen Dreiwegeplan eingeschlagen:



  1. Es gibt das Formular, 
  2. abgesichert durch ein "Google"-reCaptcha, das mir auch Hilft meine eMail-Adressen abzusichern.
  3. Und verborgene eMail-Adressen (durch Unicodes).
Nun, zum Formular muß ich glaube ich nichts sagen, daß sollten Sie im Baukasten haben (falls nicht senden Sie mir eine eMail, ich sende Ihnen gerne den Quellcode).

Das reCaptcha gibt es bei "Google" unter https://www.google.com/recaptcha/intro/index.html
Ob Sie dies verwenden oder eine eigene Lösung bevorzugen, bleibt Ihnen überlassen, ich wollte "das Rad nicht neu erfinden" (obwohl ich eine eigene Lösung in der Schublade habe). Auf alle Fälle müssen Sie herausfinden, ob das reCaptcha ausgelöst wurde, dafür hat Komail Haider unter http://www.codeproject.com/Tips/884193/Google-ReCaptcha-ASP-net-Control eine Lösung bereit (wer nicht selbst schreiben will). Das kleine Stück Software müssen Sie auf der Seite registrieren:
<%@ Register Assembly="GoogleReCaptcha" Namespace="GoogleReCaptcha" TagPrefix="wjk" %>


Wo das reCaptcha erscheinen soll binden Sie den folgenden Code ein:
<wjk:GoogleReCaptcha ID="ctrlGoogleReCaptcha" runat="server" PublicKey="BEKOMMEN SIE VON GOOGLE" PrivateKey="BEKOMMEN SIE VON GOOGLE" />

Jetzt müssen wir nur noch auswerten:

        protected void btnSend_Click(object sender, EventArgs e)        {            try            {                if (!ctrlGoogleReCaptcha.Validate())                {                    Exception reCaptchaException = new Exception("reCaptcha wurde nicht bestätigt!");                    throw reCaptchaException;                }(...)


Wie Sie sehen, wird einfach ein Fehler ausgelöst, sollte das reCaptcha nicht bestätigt sein.

Soviel zum Versenden der eMail per Formular und mit dem reCaptcha. Wie bereits erwähnt soll das reCaptcha auch dazu dienen, meine eMail-Adressen zu schützen. Auf meiner Site werden keine Adressen angezeigt, sollte ein Besucher die Adressen jedoch unbedingt haben wollen, muß er das reCaptcha bestätigen und bekommt sie angezeigt: Zuvor ist der Seitenabschnitt "hidden":


            <div id="hidden" runat="server" visible="false">
                <script type="text/javascript">                    email("&#105;&#110;&#102;&#111;", "&#119;&#97;&#108;&#116;&#101;&#114;&#45;&#107;&#111;&#104;&#108;", "&#99;&#104;", "Meine Homepage-Account");                    
                </script>            </div>

Im Quellcode wird aus "visible=false" einfach "visible=true" gemacht:

        protected void btnEmail_Click(object sender, EventArgs e)        {            try            {                if (!ctrlGoogleReCaptcha.Validate())                {                    Exception reCaptchaException = new Exception("reCaptcha wurde nicht bestätigt!");                    throw reCaptchaException;                }                hidden.Visible = true;                visible.Visible = false;            }            catch (Exception ex)            {                lblEmails.Text = "Bei der Anzeige der eMail-Adressen ist ein Fehler aufgetreten:<br />";                lblEmails.Text += ex.Message;            }        }



Was Sie im ohrigen Codeausschnitt jedoch auch sehen, sind die eMail-Adressen per Unicode verschlüsselt und werden erst durch ein wenig "JavaScript" sichtbar. Zudem werden die eMail-Adressen erst durch das JavaScript zusammen gebaut, so sind sie schwerer als eMail-Adresse zu erkennen.

    <script type="text/javascript">
        function email(name, domain, tld, link) {
            var link = "<img src='images/mailto.gif' alt='Briefcuvert' />&nbsp;<a href='&#109;&#97;&#105;&#108;&#116;&#111;&#58;" + name + "&#64;" + domain + "." + tld + "'>" + link + "</a><br />";
            document.write(link);
        }
    </script>

Damit Sie Ihre eMail-Adresse nicht händig umwandeln müssen, gibt es hier ein Tool. das Ihnen die Arbeit abnimmt: http://www.sql-und-xml.de/unicode-database/online-tools/

Sie können sich das ganze natürlich live ansehen: http://www.walter-kohl.ch/contact.aspx