Here is my code.
index.php
<?php
// First we execute our common code to connection to the database and start the session
$localhost = "localhost";
$user = "root";
$password = "";
$database = "user";
$mysqli = new mysqli($localhost, $user, $password, $database);
$error = false;
// If login form submitted
if (isset($_POST['username']))
{
// Check fields
if (empty($_POST['username']))
{
$error = 'Please enter your user name';
}
elseif (empty($_POST['password']))
{
$error = 'Please enter your password';
}
else
{
// Compose query
$query = "
SELECT
id,
username,
password,
salt
FROM users
WHERE
username = :username
";
// Params for the query
$query_params = array(
':username' => $_POST['username']
);
try
{
// Execute
$stmt = $db->prepare($query);
$result = $stmt->execute($query_params);
// Check if one row was found with the username
$row = $stmt->fetch();
if($row)
{
// Check password with secure hash and salt
$check_password = hash('sha256', $_POST['password'] . $row['salt']);
if($check_password === $row['password'])
{
// Bingo! Remove hash and salt to increase security and store user in session
unset($row['salt']);
unset($row['password']);
$_SESSION['user'] = $row;
}
{
// Wrong password
$error = 'Wrong user/password, please try again';
}
}
}
catch(PDOException $ex)
{
$error = 'Failed to run query: ' . $ex->getMessage();
}
}
// Check if AJAX request
$ajax = (isset($_SERVER['HTTP_X_REQUESTED_WITH']) and strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest');
if ($ajax)
{
header('Cache-Control: no-cache, must-revalidate');
header('Expires: '.date('r', time()+(86400*365)));
header('Content-type: application/json');
echo json_encode(array(
'logged' => !$error,
'error' => $error
));
exit();
}
elseif (!$error)
{
header('Location: dashboard.php');
exit();
}
}
?>
<!DOCTYPE html>
<!--[if IEMobile 7]><html class="no-js iem7 oldie linen"><![endif]-->
<!--[if (IE 7)&!(IEMobile)]><html class="no-js ie7 oldie linen" lang="en"><![endif]-->
<!--[if (IE 8)&!(IEMobile)]><html class="no-js ie8 oldie linen" lang="en"><![endif]-->
<!--[if (IE 9)&!(IEMobile)]><html class="no-js ie9 linen" lang="en"><![endif]-->
<!--[if (gt IE 9)|(gt IEMobile 7)]><!--><html class="no-js linen" lang="en"><!--<![endif]-->
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Stevens Fine Homes</title>
<meta name="description" content="">
<meta name="author" content="">
<!-- http://davidbcalhoun.com/2010/viewport-metatag -->
<meta name="HandheldFriendly" content="True">
<meta name="MobileOptimized" content="320">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<!-- For all browsers -->
<link rel="stylesheet" href="css/reset.css?v=1">
<link rel="stylesheet" href="css/style.css?v=1">
<link rel="stylesheet" href="css/colors.css?v=1">
<link rel="stylesheet" media="print" href="css/print.css?v=1">
<!-- For progressively larger displays -->
<link rel="stylesheet" media="only all and (min-width: 480px)" href="css/480.css?v=1">
<link rel="stylesheet" media="only all and (min-width: 768px)" href="css/768.css?v=1">
<link rel="stylesheet" media="only all and (min-width: 992px)" href="css/992.css?v=1">
<link rel="stylesheet" media="only all and (min-width: 1200px)" href="css/1200.css?v=1">
<!-- For Retina displays -->
<link rel="stylesheet" media="only all and (-webkit-min-device-pixel-ratio: 1.5), only screen and (-o-min-device-pixel-ratio: 3/2), only screen and (min-device-pixel-ratio: 1.5)" href="css/2x.css?v=1">
<!-- Additional styles -->
<link rel="stylesheet" href="css/styles/form.css?v=1">
<link rel="stylesheet" href="css/styles/switches.css?v=1">
<!-- Login pages styles -->
<link rel="stylesheet" media="screen" href="css/login.css?v=1">
<!-- Javascript at bottom except for Modernizr -->
<script src="js/libs/modernizr.custom.js"></script>
<!-- For Modern Browsers -->
<link rel="shortcut icon" href="img/favicons/favicon.png">
<!-- For everything else -->
<link rel="shortcut icon" href="img/favicons/favicon.ico">
<!-- For retina screens -->
<link rel="apple-touch-icon-precomposed" sizes="114x114" href="img/favicons/apple-touch-icon-retina.png">
<!-- For iPad 1-->
<link rel="apple-touch-icon-precomposed" sizes="72x72" href="img/favicons/apple-touch-icon-ipad.png">
<!-- For iPhone 3G, iPod Touch and Android -->
<link rel="apple-touch-icon-precomposed" href="img/favicons/apple-touch-icon.png">
<!-- iOS web-app metas -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<!-- Startup image for web apps -->
<link rel="apple-touch-startup-image" href="img/splash/ipad-landscape.png" media="screen and (min-device-width: 481px) and (max-device-width: 1024px) and (orientation:landscape)">
<link rel="apple-touch-startup-image" href="img/splash/ipad-portrait.png" media="screen and (min-device-width: 481px) and (max-device-width: 1024px) and (orientation:portrait)">
<link rel="apple-touch-startup-image" href="img/splash/iphone.png" media="screen and (max-device-width: 320px)">
<!-- Microsoft clear type rendering -->
<meta http-equiv="cleartype" content="on">
<!-- IE9 Pinned Sites: http://msdn.microsoft.com/en-us/library/gg131029.aspx -->
<meta name="application-name" content="Developr Admin Skin">
<meta name="msapplication-tooltip" content="Cross-platform admin template.">
<meta name="msapplication-starturl" content="http://www.display-inline.fr/demo/developr">
<!-- These custom tasks are examples, you need to edit them to show actual pages -->
<meta name="msapplication-task" content="name=Agenda;action-uri=http://www.display-inline.fr/demo/developr/agenda.html;icon-uri=http://www.display-inline.fr/demo/developr/img/favicons/favicon.ico">
<meta name="msapplication-task" content="name=My profile;action-uri=http://www.display-inline.fr/demo/developr/profile.html;icon-uri=http://www.display-inline.fr/demo/developr/img/favicons/favicon.ico">
</head>
<body>
<div id="container">
<hgroup id="login-title" class="large-margin-bottom">
<h1 class="login-title-image">Stevens Fine Homes</h1>
</hgroup>
<div id="form-wrapper">
<div id="form-block" class="scratch-metal">
<div id="form-viewport">
<!-- Login Section -->
<form method="post" action="admin.php" id="form-login" class="input-wrapper blue-gradient glossy" title="Login">
<ul class="inputs black-input large">
<!-- The autocomplete="off" attributes is the only way to prevent webkit browsers from filling the inputs with yellow -->
<li><span class="icon-user mid-margin-right"></span><input type="text" name="username" id="username" value="" class="input-unstyled" placeholder="Login" autocomplete="off"></li>
<li><span class="icon-lock mid-margin-right"></span><input type="password" name="password" id="pass" value="" class="input-unstyled" placeholder="Password" autocomplete="off"></li>
</ul>
<p class="button-height">
<button type="submit" class="button glossy float-right" id="login">Login</button>
<input type="checkbox" name="remind" id="remind" value="1" checked="checked" class="switch tiny mid-margin-right with-tooltip" title="Enable auto-login">
<label for="remind">Remember</label>
</p>
</form>
<!-- Recover Password Section -->
<form method="post" action="" id="form-password" class="input-wrapper blue-gradient glossy" title="Lost password?">
<p class="message">
If you can't remember your password, fill the input below with your e-mail and we'll send you a new one:
<span class="block-arrow"><span></span></span>
</p>
<ul class="inputs black-input large">
<li><span class="icon-mail mid-margin-right"></span><input type="email" name="mail" id="mail" value="" class="input-unstyled" placeholder="Your e-mail" autocomplete="off"></li>
</ul>
<button type="submit" class="button glossy full-width" id="send-password">Send new password</button>
</form>
<!-- Register Section -->
<form method="post" action="wizard.php" id="form-register" class="input-wrapper blue-gradient glossy" title="Register">
<button type="submit" class="button glossy full-width" id="send-register">Click to Register</button>
</form>
</div>
</div>
</div>
</div>
<!-- Javascript at the bottom for fast page loading -->
<!-- Scripts -->
<script src="js/libs/jquery-1.7.2.min.js"></script>
<script src="js/setup.js"></script>
<!-- Template functions -->
<script src="js/developr.input.js"></script>
<script src="js/developr.message.js"></script>
<script src="js/developr.notify.js"></script>
<script src="js/developr.tooltip.js"></script>
<script>
/*
* How do I hook my login script to these?
* --------------------------------------
*
* These scripts are meant to be non-obtrusive: if the user has disabled javascript or if an error occurs, the forms
* works fine without ajax.
*
* The only part you need to edit are the scripts between the EDIT THIS SECTION tags, which do inputs validation and
* send data to server. For instance, you may keep the validation and add an AJAX call to the server with the user
* input, then redirect to the dashboard or display an error depending on server return.
*
* Or if you don't trust AJAX calls, just remove the event.preventDefault() part and let the form be submitted.
*/
$(document).ready(function()
{
/*
* JS login effect
* This script will enable effects for the login page
*/
// Elements
var doc = $('html').addClass('js-login'),
container = $('#container'),
formWrapper = $('#form-wrapper'),
formBlock = $('#form-block'),
formViewport = $('#form-viewport'),
forms = formViewport.children('form'),
// Doors
topDoor = $('<div id="top-door" class="form-door"><div></div></div>').appendTo(formViewport),
botDoor = $('<div id="bot-door" class="form-door"><div></div></div>').appendTo(formViewport),
doors = topDoor.add(botDoor),
// Switch
formSwitch = $('<div id="form-switch"><span class="button-group"></span></div>').appendTo(formBlock).children(),
// Current form
hash = (document.location.hash.length > 1) ? document.location.hash.substring(1) : false,
// If layout is centered
centered,
// Store current form
currentForm,
// Animation interval
animInt,
// Work vars
maxHeight = false,
blocHeight;
/******* EDIT THIS SECTION *******/
/*
* Login
* These functions will handle the login process through AJAX
*/
$('#form-login').submit(function(event)
{
// Values
var username = $.trim($('#username').val()),
pass = $.trim($('#pass').val());
// Check inputs
if (username.length === 0)
{
// Display message
displayError('Please fill in your username');
return false;
}
else if (pass.length === 0)
{
// Remove empty username message if displayed
formWrapper.clearMessages('Please fill in your username');
// Display message
displayError('Please fill in your password');
return false;
}
else
{
// Remove previous messages
formWrapper.clearMessages();
// Show progress
displayLoading('Checking credentials...');
// Stop normal behavior
event.preventDefault();
// AJAX call and also where I think the problem might be!!!!
$.ajax(url, {
data: {
username: username,
pass: pass
},
success: function(data)
{
if (data.logged)
{
document.location.href = 'dashboard.php';
}
else
{
formWrapper.clearMessages();
displayError(data.error || 'Invalid user/password, please try again');
}
},
error: function()
{
formWrapper.clearMessages();
displayError('Error while contacting server, please try again');
}
});
}
});
/*
* Password recovery
*/
$('#form-password').submit(function(event)
{
// Values
var mail = $.trim($('#mail').val());
// Check inputs
if (mail.length === 0)
{
// Display message
displayError('Please fill in your email');
}
else if (!/^[a-z0-9!#$%&'*+\/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+\/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/.test(mail))
{
// Remove empty email message if displayed
formWrapper.clearMessages('Please fill in your email');
// Display message
displayError('Email is not valid');
return false;
}
else
{
// Remove previous messages
formWrapper.clearMessages();
// Show progress
displayLoading('Sending credentials...');
// Stop normal behavior
event.preventDefault();
/*
* This is where you may do your AJAX call
*/
// Simulate server-side check
setTimeout(function() {
document.location.href = './'
}, 2000);
}
});
/*
* Register
*/
$('#form-register').submit(function(event)
{
// Values
var name = $.trim($('#name-register').val()),
mail = $.trim($('#mail-register').val()),
username = $.trim($('#username-register').val()),
pass = $.trim($('#pass-register').val());
// Remove previous messages
formWrapper.clearMessages();
// Check inputs
if (name.length === 0)
{
// Display message
displayError('Please fill in your name');
return false;
}
else if (mail.length === 0)
{
// Display message
displayError('Please fill in your email');
return false;
}
else if (!/^[a-z0-9!#$%&'*+\/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+\/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/.test(mail))
{
// Display message
displayError('Email is not valid');
return false;
}
else if (username.length === 0)
{
// Display message
displayError('Please fill in your username');
return false;
}
else if (pass.length === 0)
{
// Display message
displayError('Please fill in your password');
return false;
}
else
{
// Show progress
displayLoading('Registering...');
// Stop normal behavior
event.preventDefault();
/*
* This is where you may do your AJAX call
*/
// Simulate server-side check
setTimeout(function() {
document.location.href = './'
}, 2000);
}
});
/******* END OF EDIT SECTION *******/
/*
* Animated login
*/
// Prepare forms
forms.each(function(i)
{
var form = $(this),
height = form.outerHeight(),
active = (hash === false && i === 0) || (hash === this.id),
color = this.className.match(/[a-z]+-gradient/) ? ' '+(/([a-z]+)-gradient/.exec(this.className)[1])+'-active' : '';
// Store size
form.data('height', height);
// Min-height for mobile layout
if (maxHeight === false || height > maxHeight)
{
maxHeight = height;
}
// Button in the switch
form.data('button', $('<a href="#'+this.id+'" class="button anthracite-gradient'+color+(active ? ' active' : '')+'">'+this.title+'</a>')
.appendTo(formSwitch)
.data('form', form));
// If active
if (active)
{
// Store
currentForm = form;
// Height of viewport
formViewport.height(height);
}
else
{
// Hide for now
form.hide();
}
});
// Main bloc height (without form height)
blocHeight = formBlock.height()-currentForm.data('height');
// Handle resizing (mostly for debugging)
function handleLoginResize()
{
// Detect mode
centered = (container.css('position') === 'absolute');
// Set min-height for mobile layout
if (!centered)
{
formWrapper.css('min-height', (blocHeight+maxHeight+20)+'px');
container.css('margin-top', '');
}
else
{
formWrapper.css('min-height', '');
if (parseInt(container.css('margin-top'), 10) === 0)
{
centerForm(currentForm, false);
}
}
};
// Register and first call
$(window).bind('normalized-resize', handleLoginResize);
handleLoginResize();
// Switch behavior
formSwitch.on('click', 'a', function(event)
{
var link = $(this),
form = link.data('form'),
previousForm = currentForm;
event.preventDefault();
if (link.hasClass('active'))
{
return;
}
// Refresh forms sizes
forms.each(function(i)
{
var form = $(this),
hidden = form.is(':hidden'),
height = form.show().outerHeight();
// Store size
form.data('height', height);
// If not active
if (hidden)
{
// Hide for now
form.hide();
}
});
// Clear messages
formWrapper.clearMessages();
// If an animation is already running
if (animInt)
{
clearTimeout(animInt);
}
formViewport.stop(true);
// Update active button
currentForm.data('button').removeClass('active');
link.addClass('active');
// Set as current
currentForm = form;
// if CSS transitions are available
if (doc.hasClass('csstransitions'))
{
// Close doors - step 1
doors.removeClass('door-closed').addClass('door-down');
animInt = setTimeout(function()
{
// Close doors, step 2
doors.addClass('door-closed');
animInt = setTimeout(function()
{
// Hide previous form
previousForm.hide();
// Show target form
form.show();
// Center layout
centerForm(form, true);
// Height of viewport
formViewport.animate({
height: form.data('height')+'px'
}, function()
{
// Open doors, step 1
doors.removeClass('door-closed');
animInt = setTimeout(function()
{
// Open doors - step 2
doors.removeClass('door-down');
}, 300);
});
}, 300);
}, 300);
}
else
{
// Close doors
topDoor.animate({ top: '0%' }, 300);
botDoor.animate({ top: '50%' }, 300, function()
{
// Hide previous form
previousForm.hide();
// Show target form
form.show();
// Center layout
centerForm(form, true);
// Height of viewport
formViewport.animate({
height: form.data('height')+'px'
}, {
/* IE7 is a bit buggy, we must force redraw */
step: function(now, fx)
{
topDoor.hide().show();
botDoor.hide().show();
formSwitch.hide().show();
},
complete: function()
{
// Open doors
topDoor.animate({ top: '-50%' }, 300);
botDoor.animate({ top: '105%' }, 300);
formSwitch.hide().show();
}
});
});
}
});
// Initial vertical adjust
centerForm(currentForm, false);
/*
* Center function
* @param jQuery form the form element whose height will be used
* @param boolean animate whether or not to animate the position change
* @param string|element|array any jQuery selector, DOM element or set of DOM elements which should be ignored
* @return void
*/
function centerForm(form, animate, ignore)
{
// If layout is centered
if (centered)
{
var siblings = formWrapper.siblings().not('.closing'),
finalSize = blocHeight+form.data('height');
// Ignored elements
if (ignore)
{
siblings = siblings.not(ignore);
}
// Get other elements height
siblings.each(function(i)
{
finalSize += $(this).outerHeight(true);
});
// Setup
container[animate ? 'animate' : 'css']({ marginTop: -Math.round(finalSize/2)+'px' });
}
};
/**
* Function to display error messages
* @param string message the error to display
*/
function displayError(message)
{
// Show message
var message = formWrapper.message(message, {
append: false,
arrow: 'bottom',
classes: ['red-gradient'],
animate: false // We'll do animation later, we need to know the message height first
});
// Vertical centering (where we need the message height)
centerForm(currentForm, true, 'fast');
// Watch for closing and show with effect
message.bind('endfade', function(event)
{
// This will be called once the message has faded away and is removed
centerForm(currentForm, true, message.get(0));
}).hide().slideDown('fast');
};
/**
* Function to display loading messages
* @param string message the message to display
*/
function displayLoading(message)
{
// Show message
var message = formWrapper.message('<strong>'+message+'</strong>', {
append: false,
arrow: 'bottom',
classes: ['blue-gradient', 'align-center'],
stripes: true,
darkStripes: false,
closable: false,
animate: false // We'll do animation later, we need to know the message height first
});
// Vertical centering (where we need the message height)
centerForm(currentForm, true, 'fast');
// Watch for closing and show with effect
message.bind('endfade', function(event)
{
// This will be called once the message has faded away and is removed
centerForm(currentForm, true, message.get(0));
}).hide().slideDown('fast');
};
});
</script>
</body>
</html>
Here is my user.sql
-- phpMyAdmin SQL Dump -- version 3.5.2 -- http://www.phpmyadmin.net -- -- Host: localhost -- Generation Time: Sep 25, 2012 at 01:39 AM -- Server version: 5.5.25a -- PHP Version: 5.4.4 SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO"; SET time_zone = "+00:00"; /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!40101 SET NAMES utf8 */; -- -- Database: `user` -- -- -------------------------------------------------------- -- -- Table structure for table `users` -- CREATE TABLE IF NOT EXISTS `users` ( `id` int(11) NOT NULL AUTO_INCREMENT, `first_name` varchar(255) COLLATE utf8_unicode_ci NOT NULL, `last_name` varchar(255) COLLATE utf8_unicode_ci NOT NULL, `gender` varchar(255) COLLATE utf8_unicode_ci NOT NULL, `username` varchar(255) COLLATE utf8_unicode_ci NOT NULL, `imagelocation` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, `resize_height` varchar(255) COLLATE utf8_unicode_ci NOT NULL, `crop` varchar(255) COLLATE utf8_unicode_ci NOT NULL, `mail` varchar(255) COLLATE utf8_unicode_ci NOT NULL, `phone` varchar(255) COLLATE utf8_unicode_ci NOT NULL, `position` varchar(255) COLLATE utf8_unicode_ci NOT NULL, `password` char(64) COLLATE utf8_unicode_ci NOT NULL, `security_question` varchar(255) COLLATE utf8_unicode_ci NOT NULL, `answer` varchar(255) COLLATE utf8_unicode_ci NOT NULL, `salt` char(16) COLLATE utf8_unicode_ci NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `username` (`username`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=21 ; -- -- Dumping data for table `users` -- INSERT INTO `users` (`id`, `first_name`, `last_name`, `gender`, `username`, `imagelocation`, `resize_height`, `crop`, `mail`, `phone`, `position`, `password`, `security_question`, `answer`, `salt`) VALUES (1, 'Neil', 'Horne', 'male', 'Neil', 'avatars/1809289224.png', '320', 'on', 'nhorne@itmctech.com', '910-742-9125', 'Web Novice', 'b24a2d48a3b9e192117abaf8c53dea8d8e2685a270ea31dfd2fc1cf239700049', 'question_1', 'jabba', '5cf916c59d9a37a'); /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
If someone can help me sort this our you I will forever be in your debt.
Neil
This post has been edited by Java Neil: 24 September 2012 - 05:08 PM

New Topic/Question
Reply



MultiQuote







|