Hej.
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] define('BANTIME', 15
); // How long should IP ban after X fail login attempts last [in minutes] define('MAX_ATTEMPTS', 5
); // Max. number of fail login attempts (int > 0)
/*
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'];
$File = $Break[count($Break) - 1
];
if( isset($_GET['logout']) ) {
$_SESSION['SLS_LOGGED'] = false;
header( 'Location: ' . $File );
}
// Check if max fail login attempts is 1 or greater
if( MAX_ATTEMPTS < 1 )
die('Max attempts must be 1 or grater!');
// Form submit
if ( isset($_POST['commit']) ) {
$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
{
// 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' );
die( ); // Terminate after fail login attempt
}
// Login success
else
{
removeBans($FoundAttempt); // Remove bancount/ban (if any)
$DOM->save('authPage.xml');
$_SESSION['SLS_LOGGED'] = true; // Logged in
$_SESSION['SLS_TIMEOUT'] = time( ) + $Timeout; // Timeout
unset($_POST); // Browser keep the post data anyway *dang*
header( 'Location: ' . $File ); // But we will force it to drop them!
die( ); // Always secured
}
}
// No form has been submitted
else
{
// Check if session expired.
if( isset($_SESSION['SLS_TIMEOUT']) && time( ) > $_SESSION['SLS_TIMEOUT'] ) {
$_SESSION['SLS_LOGGED'] = false;
showLoginPasswordProtect('Session expired.');
}
// Check if logged in
if( !$_SESSION['SLS_LOGGED'] )
{
showLoginPasswordProtect('');
}
// If logged in, keep session alive
$_SESSION['SLS_TIMEOUT'] = time( ) + $Timeout;
}
// 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 -->
<form method="post" action="
<? print $GLOBALS['File'] ?>">
<h1>Log in</h1>
<div class="formbody">
<?
print '<div class="error_box">' . $error . '</div>';
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.csshttp://ideone.com/ZtPJl (nie zmieściło się do posta + mało istotne)
--- QUIT ---
Ten post edytował Morfi777 4.02.2012, 12:25:13