Założenie jest aby nie używać baz danych.
Funkcjonalności:
* Logowanie jako użytkownik + hasło lub samo hasło
* Max. próba logowań (bazowano na IP logującego)
* Prostota? (do waszej oceny)
* Bezpieczeństwo? (do waszej oceny)
*

Dzięki!
PS: Tak, styl forma jest zerżnięty z Githuba, proszę już mnie za to nie karcić.
edit: dodałem komentarze

Usage
<? require_once('authPage.php'); ?>
authPage.php
<? /* Config BEGIN username => password username should contain alphameric chars only */ 'admin' => 'password', 'user' => 'qwert123', ); define('USERNAMES', true); // Choose between using Username or Username + Password auth (true/false) define('TIMEOUT', 30); // How long user should stay logged in (set 0 for unlimited time) [in minutes] /* Cofnig END Do NOT edit code below (unless you know what you are doing) */ $Timeout = TIMEOUT == 0 ? pow(999, 3) : TIMEOUT * 60; $Bantime = BANTIME * 60; $RemoteIP = $_SERVER['REMOTE_ADDR']; // Retrieve file name $FilePath = $_SERVER['SCRIPT_NAME']; $_SESSION['SLS_LOGGED'] = false; } // Check if max fail login attempts is 1 or greater if( MAX_ATTEMPTS < 1 ) // Form submit { $Password = $_POST['access_password']; $LeftAttempts = 0; // Load ban XML $DOM = new DOMDocument(); $DOM->load('authPage.xml'); $Attempts = $DOM->getElementsByTagName('attempt'); $Found = false; $FoundAttempt = NULL; foreach( $Attempts as $Attempt ) { // Check if IP already exists in XML [ref 01] if( $Attempt->getElementsByTagName('Remoteip')->item(0)->getAttribute('val') == $RemoteIP ); { $Found = true; $FoundAttempt = $Attempt; // Check if IP is already banned if ( $FoundAttempt->getElementsByTagName('Banned')->item(0)->getAttribute('val') == '1' ) { // Check if bantime already passed $TimePassed = time( ) - $FoundAttempt->getElementsByTagName('Timestamp')->item(0)->getAttribute('val'); if ( $TimePassed > $Bantime ) { // It did, therefore remove the ban and continue executing removeBans($FoundAttempt); } else { // It didn't, show Login form with banned message and terminate showLoginPasswordProtect('Banned.'); } } } } // If IP wasn't found in XML, create an entry and store first login attempt [ref 02] if( !$Found ) { $_MainNode = $DOM->createElement('attempt'); $DOM->getElementsByTagName('attempts')->item(0)->appendChild($_MainNode); $_Remoteip = $_MainNode->appendChild( $DOM->createElement( 'Remoteip' ) ); $_Remoteip->setAttribute('val', $RemoteIP); $_Attempts = $_MainNode->appendChild( $DOM->createElement( 'Attempts' ) ); $_Attempts->setAttribute('val', '1'); $_Banned = $_MainNode->appendChild( $DOM->createElement( 'Banned' ) ); $_Banned->setAttribute('val', '0'); $_Timestamp = $_MainNode->appendChild( $DOM->createElement( 'Timestamp' ) ); $_Timestamp->setAttribute('val', '0'); $LeftAttempts = MAX_ATTEMPTS - 1; $DOM->save('authPage.xml'); } // Login FAILED if ( !USERNAMES && !in_array($Password, $DATA) || ( USERNAMES && ( !array_key_exists(strtolower(trim($Login)), $DATA) || $DATA[strtolower(trim($Login))] != $Password ) ) ) { // IP has been previously found [ref 01] if ( $Found ) { $AttempsCount = $FoundAttempt->getElementsByTagName('Attempts')->item(0)->getAttribute('val'); // Retrieve number of attempts $AttempsCount++; // Increase attempts count by one // Check if number of attempts matches (or exceeds -- possible?) max number of fail login attempts... if( $AttempsCount < MAX_ATTEMPTS ) { $LeftAttempts = MAX_ATTEMPTS - $AttempsCount; // Var to display left no of attempts $FoundAttempt->getElementsByTagName('Attempts')->item(0)->removeAttribute('val'); $FoundAttempt->getElementsByTagName('Attempts')->item(0)->setAttribute('val', $AttempsCount); // Change attempts no showLoginPasswordProtect('Incorrect Login and/or Password. ' . $LeftAttempts . ' attempt(s) left' ); } // If so, ban IP address else { $FoundAttempt->getElementsByTagName('Banned')->item(0)->removeAttribute('val'); $FoundAttempt->getElementsByTagName('Banned')->item(0)->setAttribute('val', '1'); // Ban $FoundAttempt->getElementsByTagName('Timestamp')->item(0)->removeAttribute('val'); $FoundAttempt->getElementsByTagName('Timestamp')->item(0)->setAttribute('val', time()); // Timestamp when banned showLoginPasswordProtect('Banned.'); } $DOM->save('authPage.xml'); } // Display login form (ip not found) [ref 02] else showLoginPasswordProtect('Incorrect Login and/or Password. ' . $LeftAttempts . ' attempt(s) left' ); } // Login success else { removeBans($FoundAttempt); // Remove bancount/ban (if any) $DOM->save('authPage.xml'); $_SESSION['SLS_LOGGED'] = true; // Logged in } } // No form has been submitted else { // Check if session expired. { $_SESSION['SLS_LOGGED'] = false; showLoginPasswordProtect('Session expired.'); } // Check if logged in if( !$_SESSION['SLS_LOGGED'] ) { showLoginPasswordProtect(''); } // If logged in, keep session alive } // Display login form function showLoginPasswordProtect($error) { ?> <html lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Login Panel</title> <link href="authPage.css" type="text/css" rel="stylesheet"/> </head> <body> <div class="login_form" id="login"> <!-- Login form template `borrowed` from Github.com --> <h1>Log in</h1> <div class="formbody"> <? if ( USERNAMES ) { ?> <label for="login_field"> Login<br /> <input type="text" tabindex="1" style="width: 21em;" name="access_login" id="login_field" class="text" autocapitalize="off"> </label> <? } ?> <label for="password"> Password<br /> <input type="password" value="" tabindex="2" style="width: 21em;" name="access_password" id="password" class="text" autocomplete="disabled"> </label> <label class="submit_btn"> <input type="submit" value="Log in" tabindex="3" name="commit"> </label> </div> </form> </div> </body> </html> <? } // Remove bans function function removeBans($input) { $input->getElementsByTagName('Attempts')->item(0)->removeAttribute('val'); $input->getElementsByTagName('Attempts')->item(0)->setAttribute('val', '0'); $input->getElementsByTagName('Banned')->item(0)->removeAttribute('val'); $input->getElementsByTagName('Banned')->item(0)->setAttribute('val', '0'); $input->getElementsByTagName('Timestamp')->item(0)->removeAttribute('val'); $input->getElementsByTagName('Timestamp')->item(0)->setAttribute('val', '0'); } ?>
authPage.xml
<?xml version="1.0" encoding="utf-8"?> <attempts></attempts>
authPage.css
http://ideone.com/ZtPJl (nie zmieściło się do posta + mało istotne)
--- QUIT ---