이있는 테스트 로그인 양식 (PHP 5.3.18). 스크립트 시작 부분의 주석은 어떻게 작동하고 어떻게 사용하는지 설명합니다.
<?php
/*
* Q22459571
*
* a Login script:
*
* There are three actions it will do:
*
* 1) Display a login screen and process the results
*
* 2) Logout a user who has been 'remembered' or 'saved' see 'admin' cookie.
*
* 3) Automatically login a user from the details in the admin' cookie.
*
* The script action is controlled by a parameter in the URL called 'action'.
*
* The 'action' values and results are as follows:
*
* 1) action='login' : will clear any cookies and force the login screen to be shown
*
* 2) action='logout' : will clear any cookies and exit the script
*
* 3) missing 'action' parameter : a) try and login using the 'admin' cookie.
* b) show the login screen if not
* able to login.
*
* The result of the script will be saved in a '$userAuth' array as follows:
*
* 1) 'email' => user email address as stored on the db.
* 2) 'passhash' => MD5 hash as stored on the database
* 3) 'remember' => boolean to indicate that the user can be logged in
* via the 'admin' cookie
* 4) 'loginMethod' => '', 'cookie', 'form'
* 5) 'loginSuccess'=> true | false
*
*/
/*
* We will use 'mysqli' functions, prepared queries and 'bind' variables/values
*/
/*
* User table:
*
* store password as a 'salted' hash
*
* Columns: 1) email -- unique id for an admin
* 2) passhash -- password as a MD5 hash
* 3) salt -- random string that we will use as a prefix to the plaintext password
* before we take the md5 hash.
*/
// database connection...
$mysqlDb = mysqli_connect('localhost', 'test', 'test', 'testmysql');
// User Authorization details will always be in here...
$userAuth = array('email' => '', 'passhash' => '', 'remember' => false,
'loginMethod' => '', 'loginSuccess' => false);
// set the login action so we can use it later
$loginAction = isset($_GET['action']) ? $_GET['action'] : '';
/*
* see what the URL action is
*/
if ($loginAction == 'logout')
{
setcookie('admin', '' , 0, '/'); // delete cookie
echo 'user logged out'; // do what you wish here
exit; // leave the script
}
if ($loginAction == 'login')
{
if (!empty($_COOKIE['admin'])) // clear the cookie to force login
{
setcookie('admin', '' , time() + 3600, '/'); // will be empty next time
}
}
elseif (!empty($_COOKIE['admin'])) // The cookie should be encrypted -- not in this version.
{
$cookie = $_COOKIE['admin'];
$emailLen = substr($cookie, 0, 3); // get the length
$b64 = substr($cookie, 3); // get b64 encoded string
$b64decoded = base64_decode($b64); // convert back to original string
// split it up...
$userAuth['email'] = substr($b64decoded, 0, $emailLen);
$userAuth['passhash'] = substr($b64decoded, $emailLen);
$userAuth['remember' ] = 1;
// ensure user is in the database and the details match...
$sql = 'SELECT email, salt from admins WHERE email = ? and passhash = ? limit 1';
$query = mysqli_prepare($mysqlDb, $sql);
$allOk = mysqli_stmt_bind_param($query, 'ss', $userAuth['email'], $userAuth['passhash']);
$allOk = mysqli_execute($query);
$queryResult = mysqli_stmt_get_result($query);
$admin = mysqli_fetch_array($queryResult);
$userAuth['loginMethod'] = 'cookie';
$userAuth['loginSuccess'] = !empty($admin['email'])
&& $admin['email'] === $userAuth['email'];
if ($userAuth['loginSuccess'])
{
echo 'user: ', $userAuth['email'], ' was logged in via the cookie...';
exit;
}
else
{
echo 'user: ', $userAuth['email'], ' cookie details are wrong!!';
exit;
}
}
/*
* We may have a login request that we need to check...
*/
if (isset($_POST['sendLogin'])) // new login attempt
{
$userAuth['loginMethod'] = 'form';
$userAuth['loginSuccess'] = false;
$userAuth['email'] = mysqli_real_escape_string($mysqlDb, $_POST['email']);
$userPass = mysqli_real_escape_string($mysqlDb, $_POST['pass']);
$userAuth['remember'] = mysqli_real_escape_string($mysqlDb, $_POST['remember']);
// will use prepared queries and bind parameters as required
$sql = 'SELECT email, passhash, salt from admins WHERE email = ? limit 1';
$query = mysqli_prepare($mysqlDb, $sql);
$allOk = mysqli_stmt_bind_param($query, 's', $userAuth['email']);
$allOk = mysqli_execute($query);
$queryResult = mysqli_stmt_get_result($query);
$admin = mysqli_fetch_array($queryResult); // admin details
if ( !empty($userAuth['email']) && $userAuth['email'] == $admin['email']
&& !empty($userPass))
{
// calculate the MD5 hash and assume it is ok
$userAuth['passhash'] = md5($admin['salt'] . $userPass);
}
if (!empty($userAuth['passhash']) && $userAuth['passhash'] === $admin['passhash']) // passwords must have matched
{
$userAuth['loginSuccess'] = true;
if ($userAuth['remember' ])
{
$emailLen = sprintf('%03u', strlen($userAuth['email']));
$cookiesave = $emailLen . base64_encode($userAuth['email'] . $userAuth['passhash']);
setcookie('admin', $cookiesave, time() + 60 * 60 * 24 * 30, '/');
}
else
{
setcookie('admin', '' , 0, '/'); // delete cookie
}
}
else
{
setcookie('admin', '' , 0, '/'); // delete cookie if unsuccessful login
echo 'Wrong Email/Password or both';
}
} // end of form login
// if successful login
if ($userAuth['loginSuccess'])
{
echo 'user: ', $userAuth['email'], ' is logged in via: ', $userAuth['loginMethod'];
exit;
}
?>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Enter Login Details</title>
</head>
<body>
<form name="login" action="/testmysql/Q22459571_cookie_base64.php
" method="post">
<label>
<span>Email:</span>
<input type="text" class="radius" name="email" value="<?php echo $userAuth['email']; ?>" />
</label>
<label>
<span>Password:</span>
<input type="password" class="radius" name="pass" value="" />
</label>
<div class="remember">
<input type="checkbox" id="remember" name="remember" value="1" <?php echo 'checked="checked"' ?> />
<label for="remember">Remember Me!</label>
</div>
<input type="submit" value="Login" name="sendLogin" class="btn" />
</form>
</body>
</html>
base64_encoding의 핵심은 'html'이 안전하다는 것입니다. 'html'땅 어디서든 그것을 전달할 수 있으며 변경되지 않습니다. 그런 다음 '&'을 붙이면 'html unsafe'가됩니다. –
일반 텍스트 비밀번호를 쿠키 X_X에 저장하지 마십시오. – DanFromGermany