WBCE CMS – Way Better Content Editing.
You are not logged in.
Ich tu es mal hier her:
Weil ich nicht möchte, dass (böse) Bots die Login-Felder sehen, hab ich mal probiert, diese erst bei Klick nachzuladen.
Verkürzt natürlich auch den Quellcode jeder Seite ein bissel.
Getestet und eingebaut in http://wbce.at/tpls/template-daflagga.html
Schnippel im Template, index.php:
[== PHP ==]
<?php if(FRONTEND_LOGIN) {
echo '<div id="showlogin"><a href="#" onclick="showloginbox(); return false;"><img src="'.TEMPLATE_DIR.'/img/key.png" alt="K" /></a><div id="login-box" style="display:none"></div></div>';
} ?>
Die Datei login.load.php im Template Verzeichnis:
[== PHP ==]
<?php
require('../../config.php');
if (defined('WB_PATH') == false) { exit("Cannot access this file directly"); }
require_once WB_PATH . '/framework/class.frontend.php';
$wb = new frontend();
$wb->get_website_settings();
$template_dir = WB_URL.'/templates/'.basename(dirname(__FILE__));
if(FRONTEND_LOGIN AND !$wb->is_authenticated() ) {
?>
<form class="loginform" name="login" action="<?php echo LOGIN_URL; ?>" method="post">
<input type="hidden" name="redirect" id="redirect_url" value="" />
<table>
<tr><td><label for="inputusername"><?php echo $TEXT['USERNAME']; ?></label>:</td><td><input id="inputusername" type="text" name="username" class="inputfield" /></td></tr>
<tr><td><label for="inputpassword"><?php echo $TEXT['PASSWORD']; ?></label>:</td><td><input id="inputpassword" type="password" name="password" class="inputfield"/></td></tr>
<tr><td> </td><td><input type="image" class="loginsubmit" src="<?php echo $template_dir; ?>/img/login.png" alt="Log In" /></td></tr>
<!-- frontend signup -->
<?php if (is_numeric(FRONTEND_SIGNUP)) { echo '<tr><td colspan="2"><a href="'.SIGNUP_URL.'">'.$TEXT['SIGNUP'].'</a></td></tr> '; } ?>
</table></form>
<?php
} else {
?>
<form class="loginform" name="logout" action="<?php echo LOGOUT_URL; ?>" method="post">
<?php echo $TEXT['WELCOME_BACK']; ?>, <?php echo $wb->get_display_name(); ?>
<input type="submit" name="submit" value="<?php echo $MENU['LOGOUT']; ?>" class="inputfield" />
<p><a href="<?php echo PREFERENCES_URL; ?>"><?php echo $MENU['PREFERENCES']; ?></a></p>
</form>
<?php } ?>
Dazu ein bissel js, in der template.js / script.js, wie auch immer.js:
[== JavaScript ==]
function showloginbox() {
var url = TEMPLATE_DIR+'/login.load.php';
var redirect_url = window.location.href;
if(document.getElementById("login-box").style.display == 'none') {
$( "#login-box" ).load(url, function() {
$('#redirect_url').val(redirect_url);
document.getElementById("login-box").style.display = 'block';
});
} else {
document.getElementById("login-box").style.display = 'none';
}
}
und das Häppchen CSS (aus daflagga):
[== CSS ==]
#showlogin {display:block; float:left; position:relative; width:30px; text-align:right; margin:6px 6px 0 0; }
#login-box {position:absolute; width:200px; left:30px; top:-10px; padding:5px; font-size:11px; z-index:2000; background: rgba(255, 255, 255, 0.9);}
#login-box .loginsubmit {border:0;}
#login-box .inputfield {width:80px; border: 1px solid #c9e8f9; padding:1px;}
DIe Bildchen dazu könnt ihr euch eh selbst runterklauen
Last edited by grindbatzn (11.12.2016 17:42:09)
Da habe ich ein wenig Bedenken:
Folgendes Scenario , die config.php wird in einen extra Ordner verlegt, weil auf verschiedenen Webhostern der Webbenutzer keine Schreibrechte im Webroot hat und immer noch gelegentlich händische Nacharbeit nötig ist um den Install gebacken zu bekommen.
Weitere Möglichkeit, die internen Abläufe ändern sich und irgendetwas hakt dann. Oder Du hebelst Sichheitsmechanismen aus....
Auf die schnelle würde ich vermutlich vorschlagen das hier am anfang des Templates oder ab der 1.2.x in der include.php des Templates
if($_GET['lbox'] =lbox) {
// Der Loginbox Anzeige Krempel
exit; // und dann einfach exit
}
Und im Javascript einfach die aktuelle Seite oder eine beliebige mit diesem Template mit GET parameter aufrufen:
var url = WB_URL+'/index.php?lbox=lbox';
oder wenn das javascript snipsel direkt im template steht
var url = '<?php echo WB_URL.$_SERVER['SCRIPT_NAME']?>?lbox=lbox';
oder zumindest so ähnlich.
Davon ab ist es für einen Bot auch kein Problem mehr das Ajax anzuzeigen, viele weiterentwickelte Bots benutzen mittlerweile die Rendering Engine von Browsern um sich ihr HTML zu holen.
Du könntest überigens wenn du die Bots verwirren möchtest auch einfach 2 hidden felder ins form bauen
username_fieldname
password_fieldname
Damit kannst du den Benutzer und Passwort Feldern beliebige Namen zuweisen.
Das User Feld könnte also name="hauab" benutzen
wenn beim feld username_fieldname der wert "hauab" als Value gesetzt ist.
<input name="hauab" type="text" \>
<input name="username_fieldname" type="hidden" value="hauab" \>
Ich muss zugeben , ich habe das Noch nie ausprobiert, aber in der Loginklasse steht das so :-)
Offline
Naja: Wenn du die config.php ersatzlos streichst, wird es wohl überall mal krachen. Du wirst ja sicher etwas machen wie include "Hole dir den Krempel woanders" ;-)
Es stimmt, dass Bots auch JS interpretieren - aber sie klicken nicht auf alle Links und warten dann, was passiert.
Mir ist nicht klar, was der Parameter betragen soll. Natürlich kann ich die Datei direkt aufrufen - das ist bei AJAX immer so. Aber was hab ich davon? Ein Stückchen HTML, das sonst eben 1:1 so im Quellcode jeder Seite steht. Und auf das ich sowieso Zugriff habe, auch wenn es unsichtbar ist (style="display:none").
Honeypot-Felder halte ich eigentlich nicht für nötig. Ich vertraue darauf, dass die login.php die Inputs richtig behandelt. ;-)
EDIT
Um Missverständnissen vorzubeugen:
Das ganze dient nicht dazu, gezielte Angriffe zu verhindern, sondern dazu, einen Bot schon gar nicht auf die Spur zu bringen.
Anders gesagt: Natürlich bietet der Reißverschluss einer Handtasche keinen Schutz vor Raub, aber man sollte nicht mit offener Tasche in der Ubahn stehen.
Last edited by grindmobil (11.12.2016 20:00:14)
Ist schon klar , nur diese Art zusätzliche Seiten zu erstellen die sich dann irgendwie das Framework laden , siehe auch die frontend Geschichten wie LoginPage , Search ....
Die Sind alle extrem unterschiedlich und deswegen in der Core Entwicklung immer ein riesen Problem. Wnn man sowas nutzt läuft man immer Gefahr , das es spontan nicht mehr funktioniert und selbst der Entwickler erst mal sagt ... öhhhh , keine Ahnung . Vielleicht wäre es garnicht so dumm für das erstellen solcher Seiten mal ein standard Procedere zu entwickeln. Leider ist das recht schwierig .. :-(
Grundsätzlich müssten wir uns auch mal Gedanken machen wie wir auf einfache Art richtige Ajax anfragen bedienen könnten. (HTML Schnipsel nachladen ist ja nicht wirklich Ajax )Dafür ist zur Zeit noch nichts vorgesehen.
Offline
Grundsätzlich müssten wir uns auch mal Gedanken machen wie wir auf einfache Art richtige Ajax anfragen bedienen könnten. (HTML Schnipsel nachladen ist ja nicht wirklich Ajax )Dafür ist zur Zeit noch nichts vorgesehen.
Was meinst Du in diesem Zusammenhang mit einer RICHTIGEN Ajax Anfrage?
Gruß,
Christian
“Success is the progressive realization of a worthy ideal.” ― Earl Nightingale
Offline
Das war ja nur eine sehr einfache Sache, keine Parameter/Werte mitgeschickt, ist ja nicht nötig.
Aber sehr interessant ist natürlich die Frage: Wie muss eine Datei aussehen, die per AJAX angesprochen wird? Sobald Berechtigungen ins Spiel kommen, muss auch das Backend reingeladen werden, aber natürlich ohne irgendwelche Ausgaben.
Oder man greift direkt auf die Sessions zu, das ist einfacher. Der Core macht auch nichts anderes, aber man hat einen irren Overhead.
Mal ganz ketzerisch gefragt: wie groß ist die Häufigkeit, dass
1. der Frontend-Login überhaupt benötigt wird (bei mir in ca. 1 von 50 Projekten) und
2. bei Webseiten mit Login es tatsächlich Benutzer gibt, die auf Screenreader angewiesen sind?Versteht mich nicht falsch, ich möchte niemanden ausschließen und unterstütze einen inkludierenden Ansatz, aber mir kommt diese hitzige Auseinandersetzung hier gerade etwas akademisch vor.
Und: falls der Ajax-basierte Login mit bestimmten Geräten oder auch abgeschaltetetn Javascript nicht funktioniert, bleibt ja immer noch als Fallback der "klassische" Login über /account/login.php, oder?
In der Tat sind Seiten mit Frontend-Login seltener bei WB/CE.
Was einen Fallback angeht, falls JS nicht aktiv ist, könnte man Chio's Code ergänzen, sodass der Link hier....
[== PHP ==]
<?php if(FRONTEND_LOGIN) {
echo '<div id="showlogin"><a href="#" onclick="showloginbox(); return false;"><img src="'.TEMPLATE_DIR.'/img/key.png" alt="K" /></a><div id="login-box" style="display:none"></div></div>';
} ?>
... statt einer Raute (#) einen Direktlink auf die selbe Seite mit angehängtem GET Parameter hat. Z.B. www.meineseite.tld/pages/seiteeins.php?logmein=1
Wenn JS aktiv, wird dieser Link ignoriert und das per JS vorgegebene Verhalten ausgelöst.
Ist JS deaktiviert funktioniert der Link und nach Betättigung wird der GET Parameter vom Skript aufgespürt und dann würde die login.load.php aufgerufen.
Um nicht doppelt und dreifach Dateien zu haben, könnte man die obige login.load.php etwas erweitern, sodass die config.php nicht geladen werden muss. Beginnend mit:
<?php
if(!defined('WB_PATH')){
// load config.php for AJAX
require('../../config.php');
if (defined('WB_PATH') == false) { exit("Cannot access this file directly"); }
require_once WB_PATH . '/framework/class.frontend.php';
$wb = new frontend();
$wb->get_website_settings();
$template_dir = WB_URL.'/templates/'.basename(dirname(__FILE__));
}
// dann den Rest aus Chio's Beispiel oben
Dann noch:
<?php
if(isset($_GET['logmein']) && $_GET['logmein'] == true){
include __DIR__.'/login.load.php'; // lade die login box
}
?>
Das wäre dann eine Fallback Lösung.
Noch etwas anpassen und dann geht das.
Das sind allerdings meiner Meinung nach Dinge, die nicht mit an Board sein müßen, da sie zu speziell sind.
Aber so ein Tutorial ist gut und praktisch, für diejenigen, die es grad mal brauchen.
Last edited by stefanek (13.12.2016 10:01:15)
“Success is the progressive realization of a worthy ideal.” ― Earl Nightingale
Offline
norhei wrote:Grundsätzlich müssten wir uns auch mal Gedanken machen wie wir auf einfache Art richtige Ajax anfragen bedienen könnten. (HTML Schnipsel nachladen ist ja nicht wirklich Ajax )Dafür ist zur Zeit noch nichts vorgesehen.
Was meinst Du in diesem Zusammenhang mit einer RICHTIGEN Ajax Anfrage?
Jetzt verstehe ich was Du meinst,
das ganze Gemüse, was man innerhalb der per Ajax aufgerufenen Datei benötigt, dass die Datei abgesichert ist, aber man weder das Frontend noch das Backend zwangsläufig laden muss, bzw. respektive $wb oder $admin.
War da nicht eine Änderung, wo Du meintest, die beiden sind mehr oder weniger gemerged worden?
So oder so, je nach Ajax Anwendung und je nachdem wo Du Dich befindest, wenn die Ajax Abgrage gestartet wird, müßen bestimmte Rechte abgefragt werden. Im Backend brauchst Du Rechte an speziellem Modul oder Tool.
Von daher kann man ein bisschen Schreiberei nicht ganz vermeiden.
Selbst wenn wir ein neues Objekt hätten... dann muss man wiederrum das neue Objekt kennenlernen.
Der PageTree und viele andere Dinge im Backend laufen ja auch mit Ajax. Dann wieder umschreiben?
nääh..
Wenn es aber gute Ideen gibt, bin ich natürlich nicht abgeneigt mir das anzuschauen.
Christian
“Success is the progressive realization of a worthy ideal.” ― Earl Nightingale
Offline
Jepp.
Das mache ich ja deswegen mit AJAX, damit Bots nicht aufmerksam werden. Da ist es natürlich ein wenig kontraproduktiv, wenn ich eine Fallback-Lösung anbiete, die genau das wieder umgeht.
Sollte jemand einen Blinden als Admin haben, wird er das individuell ändern. Abgesehen davon wird sich der wohl direkt im Backend anmelden.
AJAX im Allgemeinen:
Da gibt es allerhand Schweindlereien... ICh weiß da zb von einem älteren Modul, wo man nicht einmal angemeldet sein muss, um lustige Dinge zu machen. (nichts systemkritisches, aber man könnte überrascht sein)
So manch einer baut da einfach irgendwas ein und denkt sich, dass man das ja eh nicht sieht. Irrtum: Alles was per AJAX angesprochen wird, ist grundsätzlich von außen zugänglich.
Da hilft es auch nichts, bestimmte Werte/Parameter abzufragen - das kann man alles per Entwicklertools herausfinden und ändern.
@norhei
Wie muss der Kopfbereich eines Scriptes aussehen, das per AJAX angesteuert wird? (POST oder GET)
Annahme: $mod_dir = Modulname.
EDIT: $page_id kann übergeben werden, aber ist aber natürlich leicht manipulierbar.
EDIT:
Frontend-Login
Ich nutze ihn gerne, meist in Verbindung mit einem Edit.Schalter (den man übrigens auch super per AJAX machen könnte, statt bei jedem Seitenaufruf die ganze Wurst durchzurechnen)
Tippfehler? Schwupp, anmelden, Edit, ändern. Auch am Handy.
Kommentare bearbeiten? Auch gleich im Frontend, da brauch ich das Backend gar nicht.
Auch Itemz hat eine kleine Frontend-Edit Funktion. rFG sowieso. Ich liebe es.
Last edited by grindmobil (13.12.2016 20:13:49)
Jepp.
Das mache ich ja deswegen mit AJAX, damit Bots nicht aufmerksam werden. Da ist es natürlich ein wenig kontraproduktiv, wenn ich eine Fallback-Lösung anbiete, die genau das wieder umgeht.
Ach so. Ja gut, dann gibt's jetzt zwei Lösungen. Eine mit Fallback.
“Success is the progressive realization of a worthy ideal.” ― Earl Nightingale
Offline
Es ist leider so, dass sich Blinde (Screenreader) und Bots technisch ziemlich ähnlich sind.
Der wesentliche Unterschied: Bots haben es sehr eilig, ein Bot bleibt keine Sekunde auf der Seite.
Bei GlobalComments ist zb für einen Bot keine Kommentarbox sichtbar- auch nicht, wenn er JS/jQuery ausführt. Die Box wird etwas verzögert geladen. Auf site-check.cc hab ich das Captcha schon abeschaltet, ich glaube, ich brauche es nicht mehr.
Auch hier noch ein EDIT (laut nachdenken)
Natürlich gilt auch hier: Jedes PHP-Script, das AJAX entgegennimmt, ist von außen zugänglich. Wenn ich kein Captcha mehr habe, ist die Tür relativ weit offen. Jeder kann da reinspammen, direkt ins Script.
Solle ich plötzlich innerhalb einer Minute 100e eMails über neue Kommentare bekommen, kann ich es aber relativ schnell wieder einschalten - und Verbesserungen vornehmen.
Last edited by grindmobil (13.12.2016 20:24:07)
Nochmal zu der config.php
Folgendes Scenario , die config.php wird in einen extra Ordner verlegt, weil auf verschiedenen Webhostern der Webbenutzer keine Schreibrechte im Webroot hat und immer noch gelegentlich händische Nacharbeit nötig ist um den Install gebacken zu bekommen.
Wenn das so ist und der einzige Grund, kann man die config.php trotzdem dort belassen und einfach die sich woanders befindende, bei der Installation geschriebene config.php inkludiert werden.
// [root]/config.php
<?php
$sConfigFile = __DIR__.'/config/installation_config.php';
if(file_exists($sConfigFile)) require $sConfigFile;
So verbleiben alle alten verweise auf die config.php ungebrochen.
Gruß,
Christian
Last edited by stefanek (14.12.2016 14:33:10)
“Success is the progressive realization of a worthy ideal.” ― Earl Nightingale
Offline