...

View Full Version : Resolved Login Restriction Help



Joseph Witchard
01-20-2010, 07:10 AM
<?php

/** Coded by: Jeffrey (Joseph Witchard)
** Created on: 07/18/09
** Last modified: 01/19/10
** Purpose: To log Rebirth Staff members
** into the news system. */


if (array_key_exists('login', $_POST) && !empty($_POST['login']))
{

// include the connection and password encryption settings

require('includes/SU_conn.php');
require('includes/pwd_crypt.php');

// list expected and required fields

$expected = array('user', 'pwd');
$required = array('user', 'pwd');

// create an empty array for missing elements

$missing = array();

// process the post variables

foreach ($_POST as $key => $value)
{

// set up a temporary variable and strip whitespace if not an array

$temp = is_array($value) ? $value : trim($value);

// if empty and required, add to missing

if (empty($temp) && in_array($key, $required))
{

$missing[] = $key;

}

elseif (in_array($key, $expected))
{

// add to a variable of the same name

${$key} = $temp;

}

}

// continue only if missing is empty

if (empty($missing))
{

// don't need missing now

unset($missing);

// strip HTML characters

$user = htmlentities($user);
$pwd = htmlentities($pwd);

// encrypt and salt the password

$pwd = pwd_crypt($pwd);

// open the connection

$conn = @suAccess();

// check the connection

if (mysqli_connect_errno())
{

// let's mail me the error

require('includes/mail_mysqli_conn_error.php');

// prepare the error variables

$error = mysqli_connect_error();
$number = mysqli_connect_errno();
$database = 'news2_db';
$script = 'https://hogwarts-rpg.net' . $_SERVER['PHP_SELF'];

// execute the function

mail_mysqli_conn_error($error, $number, $database, $script);

// set up a boolean to let the user know what's happening

$no_conn = true;

}

else
{

// set up the query

$query = "SELECT last_failure, last_failure_time, user_id, admin, token, jman, username, pwd, user_email FROM users WHERE username = ? AND pwd = ? LIMIT 1";

// begin getting the data out

$stmt = $conn->prepare($query);

$stmt->bind_param('ss', $user, $pwd);

$stmt->execute();

$stmt->store_result();

// make sure we got something

if ($stmt->num_rows() > 0)
{

$stmt->bind_result($login_num, $login_time, $id, $admin, $token, $jeff, $staff_user, $staff_pwd, $staff_email);

$stmt->fetch();

if (time() < $login_time)
{

$too_fast = true;

}

elseif ($login_num > 4)
{

$login_query_2 = "UPDATE users SET last_failure = ?, last_failure_time = ? WHERE username = ?";

$login_stmt_2 = $conn->prepare($login_query_2);

$login_stmt_2->bind_param('iis', $failure_reset, $failure_time, $failed_user);

$failure_reset = 0; // this resets the number of failures
$failure_time = time() * 900; // adding this to the database will make the user unable to log in for 15 minutes
$failed_user = $user; // the user, obviously

$login_stmt_2->execute();

if ($login_stmt_2->errno)
{

// prepare to mail me the error

$error = $login_stmt_2->error;
$errno = $login_stmt_2->errno;
$database = 'news2_db';
$script = 'https://hogwarts-rpg.net' . $_SERVER['PHP_SELF'];

// mail it to me

mail_mysqli_stmt_error($error, $errno, $database, $script);

$login_stmt_2->close();

}

else
{

// close

$login_stmt_2->close();

}

// make sure they're who they say they are

if ($admin == 1 || $admin == 2)
{

// set up the session

session_name('RebirthStaff');
session_set_cookie_params(10800, '/staff', 'hogwarts-rpg.net', true);
session_start();

// set a security token

$token = md5(uniqid(rand(), true));

setcookie('token', $token, 0, '/staff/', '.hogwarts-rpg.net', true);

$_SESSION['token'] = $token;
$_SESSION['staff_news'] = true;
$_SESSION['id'] = $id;
$_SESSION['admin'] = $admin;
$_SESSION['token'] = $token;
$_SESSION['pwd'] = $staff_pwd;
$_SESSION['jeff'] = $jeff;
$_SESSION['staff_user'] = $staff_user;
$_SESSION['staff_email'] = $staff_email;


header('Location: https://hogwarts-rpg.net/staff/staff_center.php');


// commit, close, redirect, and exit

$stmt->close();

$conn->commit();

$conn->close();

exit;

}

else
{

$not_staff = true;

}

}

}


$login_query_1 = "UPDATE users SET last_failure = last_failure + 1 WHERE username = ?";

$login_stmt_1 = $conn->prepare($login_query_1);

$login_stmt_1->bind_param('s', $user);

$login_stmt_1->execute();

$login_fail = true;

// check for statement errors

if ($login_stmt_1->errno)
{

// prepare to mail it to me

$error = $login_stmt_1->error;
$errno = $login_stmt_1->errno;
$database = 'news2_db';
$script = 'https://hogwarts-rpg.net' . $_SERVER['PHP_SELF'];

// mail it to me

mail_mysqli_stmt_error($error, $errno, $database, $script);

}

}

}

}

?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr">
<head>
<title>Rebirth News System Login - Ultimate Hogwarts: The Rebirth</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<meta http-equiv="content-style-type" content="text/css"/>
<link href="/css/general.css" rel="stylesheet" type="text/css"/>
<link href="/favicon.ico" rel="shortcut icon"/>
<style type="text/css">
#login_form { margin: 0px auto; text-align: center; }
#login_form label { font-weight: bold; }
</style>
<script type="text/javascript">
function checkInput()
{

// assign the form fields to variables

var username = document.getElementById("user");
var password = document.getElementById("pwd");

// check the form for data

if (username.value == "" || username.value == "NULL")
{

window.alert("Please enter your username.");
username.focus();
return false;

}

else if (password.value == "" || password.value == "NULL")
{

window.alert("Please enter your password");
password.focus();
return false;

}

else
{

// let's go

return true;

}

}
</script>
</head>
<body>
<div id="login_form">
<h3>Rebirth News Login</h3>
<?php

if ($_POST && isset($missing))
{

echo "<p class='warning'>All fields are required. Please try again.</p>";

}

elseif ($_POST && $too_fast)
{

echo "<p class='warning'>As a security precaution, you are unable to log in for 15 minutes after your last attempt.</p>";

}

elseif ($_POST && $login_fail)
{

echo "<p class='warning'>Your login attempt failed. After five attempts, you will be unable to login for 15 minutes.</p>";

}

elseif ($_POST && $no_conn)
{

echo "<p class='warning'>There was a problem connecting to the database. The webmaster has been informed of this. Please try again later.</p>";

}

elseif ($_POST && $no_data)
{

echo "<p class='warning'>Your username or password is not recognized.</p>";

}

elseif ($_POST && $not_staff)
{

echo "<p class='warning'>Our records show that you are not a staff member.</p>";

}

elseif ($_POST && $too_fast)
{

echo "<p class='warning'>Don't login too fast!</p>";

}
?>
<form id="news_login" name="news_login" method="post" onSubmit="return checkInput();" action="https://hogwarts-rpg.net/staff/index.php">
<p><label for="user">Username:</label> <input type="text" id="user" name="user" size="20" maxlength="30"/></p>
<p><label for="pwd">Password:</label> <input type="password" id="pwd" name="pwd" size="20" maxlength="16"/></p>
<p><input type="submit" id="login" name="login" value="Login"/> <input type="reset" value="Reset"/></p>
</form>
</div>
</body>
</html>
<!-- Coded by: Jeffrey (Joseph Witchard)
** Created on: 07/19/09
** Last modified: 10/19/09
** Purpose: To give Rebirth Staff Members
** a login form. -->


I'm trying to make it where a user who fails to login too many times can't log in for 15 minutes. For some reason, though, last_failure_time in MySQL doesn't get updated. I've tried setting the field to INT, BIGINT, and TIMESTAMP. I can't figure it out.

Fou-Lu
01-20-2010, 01:11 PM
$failure_time is too large, its wrapping the max int size. You want to add 900 to it, not multiply it. Storing it as an integer will suffice in you're database.

JAY6390
01-20-2010, 01:13 PM
Use the fieldtype "timedate" and then update using NOW()

Joseph Witchard
01-21-2010, 01:45 AM
Does now() have to be uppercase? It told me it was an undefined function.

How long exactly will storing it as Int suffice? time() is going to keep getting larger, right?

Fou-Lu
01-21-2010, 02:05 AM
Does now() have to be uppercase? It told me it was an undefined function.


NOW() is a mysql command in the format 'y-m-d hh:mm:ss'. You can use it as a part of you're query. Its datatype is a datetime. SQL is case-insensitive when it comes to control flow, only you're data is preserved by case. Fields and tables are normally sensitive but this is controllable.



How long exactly will storing it as Int suffice? time() is going to keep getting larger, right?

It will last until January 19, 2038 03:07:14 (0). I'm fairly certain that the base is a signed integer, so this should be correct since I used PHP to run it (PHP does not have an unsigned integer datatype). After that, it will roll back to 'December 13, 1901 08:52:45 (0)'. If it were not for x64 and better systems, 2038 would be the 'real' year 2000.

Joseph Witchard
01-21-2010, 05:52 AM
I'm sorry, I worded that wrong. I meant to say how long will time() last until adding 900 to it will be too big for a standard MySQL Int? Before I have to alter the field into a BigInt?

Fou-Lu
01-21-2010, 12:47 PM
MySQL int is also 32 bits, so you could store a number up to 2038ish. If you're concerned about the datastorage limitations, you can use just the datetime option in mysql instead.

Joseph Witchard
01-21-2010, 01:51 PM
How would you compare datetimes in PHP? I've never done that before. Still > or <?

JAY6390
01-21-2010, 02:33 PM
http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html

Joseph Witchard
01-22-2010, 05:27 AM
Thanks for the help:)



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum