I have been working on my account creation page and I am stuck onto where I should be checking if email is already in use and how to go by it. would I need to make a query statement like this
Select * from Customers WHERE Email = $email)
and check that way?
<?php
session_start();
?>
<?php require_once("headerTH.html") ?>
<?php
$db= new PDO("sqlite:onlinestore.db");
if(ISSET($_POST['register'])){
$username = $_POST['username'];
$email = $_POST['email'];
$psw = sha1($_POST ['psw']);
$tel = $_POST['tel'];
if(! empty($email) && !empty($psw)) {
$query = "INSERT INTO Customers (UserName, Passwd, PhoneNumber, Email) VALUES(:UserName, :Passwd, :PhoneNumber, :Email)";
$result = $db->prepare($query);
$result->bindParam(":UserName", $username);
$result->bindParam(":Passwd", $psw);
$result->bindParam(":Email", $email);
$result->bindParam(":PhoneNumber", $tel);
// Account pass or fail
if($result->execute()){
echo"You have successfully created an account.{$_POST['email']}<br>";
}else{
///print_r($db->errorInfo());
require_once("create.php");
}
} else {
echo "all fields are required";
require_once("create.php");
}
} else {
require_once("create.php");
}
?>
<?php require_once("footerT.html")?>
I think the ideal way to do this is to check if the new email exists in the database, and based on that situation. The user will be able to create the account if the new email doesn't exist in the database, otherwise you should show an alert that email already exists.
Just required a simple if statment at the top
$stmt = $db->prepare("SELECT * FROM Customers WHERE Email=?");
$stmt->execute([$email]);
$user = $stmt->fetch();
if($user){
//email found
echo "Email already used";
}else if($result->execute()){
echo"You have successfully created an account.{$_POST['email']}<br>";
}else{
///print_r($db->errorInfo());
require_once("create.php");
}
} else {
echo "all fields are required";
require_once("create.php");
}
}
If it's me, YES, like what you said, I create a new function let say function checkUserByEmail($email) to check if the email already exists or not.
Then again you can use the same function if you need to check the user by email, let say at the time of login (if you using email for login).
By the way, DON't FORGET TO SANITIZE YOUR INPUTS ;)
Related
I am setting up a new website with registration and login forms. As a beginner I am usting mostly part of codes I find online and in books. I have finished registration form and it works perfectly, but now I have a problem with a login form, because all codes that I can find are based on hashed password and the login form I have to build does not need it. Can you help to convert the script I have now into script that will work without any password (instead of a password it just need a 6 digital number which is not hashed).
I tried check_login, but it did not work.
$sql = "SELECT id, email, pin FROM users WHERE email = ?";
if($stmt = $mysqli->prepare($sql)){
// Bind variables to the prepared statement as parameters
$stmt->bind_param("s", $param_email);
// Set parameters
$param_email = $email;
// Attempt to execute the prepared statement
if($stmt->execute()){
// Store result
$stmt->store_result();
// Check if username exists, if yes then verify password
if($stmt->num_rows == 1){
// Bind result variables
$stmt->bind_result($id, $username, $numerpin);
if($stmt->fetch()){
if($stmt->num_rows == 1){
// Password is correct, so start a new session
session_start();
// Store data in session variables
$_SESSION["loggedin"] = true;
$_SESSION["id"] = $id;
$_SESSION["email"] = $email;
// Redirect user to welcome page
header("location: dashboard.php");
} else{
// Display an error message if password is not valid
$numerpin_err = "The password you entered was not valid.";
}
}
} else{
// Display an error message if username doesn't exist
$email_err = "No account found with that username.";
}
} else{
echo "Oops! Something went wrong. Please try again later.";
}
}
You have this query:
"SELECT id, email, pin FROM users WHERE email = ?"
You are checking for the email to be correct. You could change it to
"SELECT id, email, pin FROM users WHERE email = ? and pin = ?"
of course, passing pin as well. Also, your error message is misleading:
if($stmt->num_rows == 1){
// Password is correct, so start a new session
session_start();
// Store data in session variables
$_SESSION["loggedin"] = true;
$_SESSION["id"] = $id;
$_SESSION["email"] = $email;
// Redirect user to welcome page
header("location: dashboard.php");
} else{
// Display an error message if password is not valid
$numerpin_err = "The password you entered was not valid.";
}
what if there are multiple records with the very same email? In that case it will say that password is incorrect, without checking its actual value. It would be much more reliable to get the record(s) by email and pin, loop the results and when a match is found, then create a session. If there is no match, then error.
As others suggested. The best approach is to use hash password but since you do not want that. you can go ahead with this. Try the code below
<?php
$mysqli = new mysqli('localhost', 'your username', 'your password', 'your db name');
if($mysqli->connect_error){
echo "cannot connect to database";
}
// assuming your post variable is set as follows
$email = $_POST['email'];
$pin = $_POST['pin'];
$stmt = $mysqli->prepare("SELECT id, email, pin FROM users WHERE email = ? AND pin = ?");
/* i is for integer and s is for string. I suspect that your pin must be integer so I set the bind to i
*/
$stmt->bind_param("si", $email, $pin);
if($stmt->execute()){
$stmt->store_result();
$result = $stmt->get_result();
$num_rows = $result->num_rows;
}
if($num_rows == 1){
// Password is correct, so start a new session
session_start();
// Store data in session variables
$_SESSION["loggedin"] = true;
$_SESSION["id"] = $id;
$_SESSION["email"] = $email;
// Redirect user to welcome page
header("location: dashboard.php");
}else{
echo "Error: Either Email or Pin number is wrong";
}
?>
This file is the action file .When user submits wrong values , it heads back to the file named vform.php and asks user the correct input. But for me , after entering correct values and clicking on register , neither values are entering into wamp db, nor showing successful message. below is the code for adding values into db. after successful validation , it heads toregsuccess.php where it shows registration successful message. I don't know what exactly is the reason why values are not entering into db .
<?php
ob_start();
session_start();
include("DBConnection.php"); // include the connection object from the
DBConnection.php
if ($_POST['submit'])
{
$inFullname = trim($_POST["name"]);
$inEmail = trim($_POST["email"]);
$inPhone = trim($_POST["phonenumber"]);
$_SESSION['valid_name']=$inFullname;
$_SESSION['valid_email']=$inEmail;
$_SESSION['valid_phone']=$inPhone;
if( !preg_match("/^([a-zA-Z' ]+)$/",$inFullname) ||!preg_match('',$inEmail) || !preg_match('',$inPhone) ){
if(preg_match("/^[a-zA-Z-,]+(\s{0,1}[a-zA-Z-, ])*$/",$inFullname)){
$_SESSION['valid_name']=$inFullname;
}else {
$_SESSION['name_error'] = "enter valid name";
}
if(preg_match("/^([A-Za-z0-9_\-\.])+\#([A-Za-z0-9_\-\.])+\.([A-
Za-z]{2,4})$/",$inEmail)){
$_SESSION['valid_email']=$inEmail;
} else{
$_SESSION['mail_error'] = "enter valid mail";
}
if(preg_match("/^\d{3}-\d{3}-\d{4}$/",$inPhone)){
$_SESSION['valid_phone']=$inPhone;
} else{
$_SESSION['phone_error'] = "enter valid phone number";
}
header('Location: vform.php');
die();
}
$stmt = $db->prepare("INSERT INTO DETAILS(NAME,EMAIL,PHONENUMBER) VALUES(?,?,?)"); //Fetching all the records with input credentials
$stmt->bind_param("sss", $inFullname,$inEmail,$inPhone); //Where s indicates string type. You can use i-integer, d-double
$stmt->execute();
$result = $stmt->affected_rows;
$stmt -> close();
$db -> close();
if($result > 0) {header("location: RegSuccess.php");} // user will be taken to the success page
else{ echo 'Oops. Something went wrong. Please try again Try Login';}
}
?>
I'm so close to completing the login/registration section of my site but I've got some bugs that don't show up in error_log or anything.
About an hour ago, the script worked for the most part. It would validate, insert into/check database, and redirect to index.php (located in user directory along with login and register forms).
Contents of index.php:
/*
If validation script is successful, continue to $destinationUrl, otherwise, go back to try
again. Ultimately, the TRUE statement's output will be the referring page's URL stored as
$_SESSION['Return_Url'] to send users back to where they were, simply as a convenience.
*/
session_start();
if(isset($_SESSION['UserData'])) {
exit(header("location:" . $destinationUrl));
} else {
exit(header("location:" . $loginUrl));
}
That's exactly what I want except one detail: it won't show any user input errors. While trying to fix that, I've managed to screw everything up again and now it still submits data and inserts into the database but doesn't insert $email, and doesn't redirect or anything. On top of that, I don't get any PHP errors so I'm at a loss.
I know the login and registration will work because it did before, but I don't know what I did to cause this issue due to know errors being thrown. I just want the input errors to show up. I'm going to post the original code I copied and edited because what I'm messing with right now is a mess but the validation section is the same.
I did not write these, they were found online after hours of trying script after script. Only this one worked. Therefore, I don't understand exactly what's going on with every part of the script, but I do understand the basic mechanics of what happens, or is supposed to happen as far as validation of input data and adding to/checking data against the database when the form is submitted. The only thing that I have absolutely no idea what and how it works is the output($var) function
Included Scripts
$db= mysqli_connect($dbhost,$dbuser,$dbpwd,$dbase); }
function safe_input($db, $data) {
return htmlspecialchars(mysqli_real_escape_string($db, trim($data)));
}
/*
Currently, I have no idea about JSON or any other languages. Only a decent
portion of PHP, and HTML, of course. Can I just forget this function and use
{return $var;} instead? Because that would make everything so much easier
and I probably wouldn't even be posting these questions... but it's a new
language to me that I couldn't tell you the first thing about.
*/
function output($Return=array()){
header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json; charset=UTF-8");
exit(json_encode($Return));
}
Validation Scripts
(Both scripts are in one file)
<?
require 'config.php';
require 'functions.php';
if(!empty($_POST) && $_POST['Action']=='login_form'){
$Return = array('result'=>array(), 'error'=>'');
$email = safe_input($db, $_POST['Email']);
$password = safe_input($db, $_POST['Password']);
if(filter_var($email, FILTER_VALIDATE_EMAIL) === false) {
$Return['error'] = "Please enter a valid email address.";
}elseif($password===''){
$Return['error'] = "Please enter password.";
}
if($Return['error']!=''){
output($Return);
}
$result = mysqli_query($db, "SELECT * FROM tbl WHERE email='$email' AND password='".md5($password)."' LIMIT 1");
if(mysqli_num_rows($result)==1){
$row = mysqli_fetch_assoc($result);
$Return['result'] = $_SESSION['UserData'] = array('id'=>$row['id']);
} else {
$Return['error'] = 'Invalid Login Credential.';
}
output($Return);
}
if(!empty($_POST) && $_POST['Action']=='registration_form'){
$Return = array('result'=>array(), 'error'=>'');
$name = safe_input($db, $_POST['Name']);
$email = safe_input($db, $_POST['Email']);
$password = safe_input($db, $_POST['Password']);
if($name===''){
$Return['error'] = "Please enter Full name.";
}elseif (filter_var($email, FILTER_VALIDATE_EMAIL) === false) {
$Return['error'] = "Please enter a valid Email address.";
}elseif($password===''){
$Return['error'] = "Please enter Password.";
}
if($Return['error']!=''){
output($Return);
}
$result = mysqli_query($db, "SELECT * FROM tbl WHERE email='$email' LIMIT 1");
if(mysqli_num_rows($result)==1){
$Return['error'] = 'The email you entered already belongs to an account, please login.';
}else{
mysqli_query($db, "INSERT INTO tbl (GUID, email, password, entry_date) values(MD5(UUID()), '$email', '".md5($password)."' ,NOW() )");
$id = mysqli_insert_id($db);
mysqli_query($db, "INSERT INTO `tbl' (id,name) VALUES('$id','$name')");
$Return['result'] = $_SESSION['UserData'] = array('id'=>$id);
}
output($Return);
}
?>
I'm not sure how I would echo the $Return array values. I tried making a function out of it like so:
function inputErr($Return) {
if($Return['error']!=''){
output($Return);
}
}
but that didn't work either. Is there a special way to echo an array value? Without the index name attached
Also, if you have any ideas why the email $var is not being added to db while everything else is, please, do share! With the script not throwing any PHP errors, I have no idea where to start.
I'm just new in PHP, I have the project which I'm still constructing and now Am working on
Administrator area.
For now I'm writing the script which Update the password in the table by looking two criteria
"username and fname" if the same with the entered one the password should change, And It does so successfully, but the problem is once I enter incorrect username it still update the password and doesn't show the message "The username you entered does not exist" as well as when I write wrong fname it doesn't show the message to, It real make me stacking where Am wrong, although I know there some where A'm wrong.
I request for any help to any one I'w be thankfully.
This my script
<?php
session_start();
//include mysqli_connect
$name = $_POST['fname'];
$newp = $_POST['newpword'];
$user=$_POST['username'];
$result = mysql_query("SELECT password FROM admin WHERE fname='$name'
AND username='$user' ");
if(!$result)
{
echo "The username you entered does not exist";
}
elseif(mysql_num_rows($result)>0)
$result=mysql_query("UPDATE admin SET password='$newp' where fname='$name'");
{
echo "Password change successfully";
echo"<br>";
echo"<a href=index.php> Click here to signin </a>";
exit;
}
{
echo "The new password and confirm new password fields must be the same";
}
?>
Your if statement and brackets are very mixed up in the code. I think I understood what you're trying to do, though... but you should really go through your own code and give everything the correct indentation.
I changed your code to use pdo.
I added a POST value for the old user password because you should really verify that, too, when updating a user password even if they are already logged in. You will need to add a field for that in the form this is being sent from. If you don't want to use it, you will just need to take the logic out of the code.
And - I really hope you aren't storing the password in plain text. If you are, please tell me what your exact PHP version is in a comment below this post and I can update my answer to show how you would go about storing and using hashed passwords. It does really depend on the version, though.
<?php
session_start();
$_POST['fname'] = 'fname';
$_POST['newpword'] = 'newpword';
$_POST['username'] = 'username';
$name = (isset($_POST['fname'])) ? $_POST['fname'] : die("\$_POST['fname'] is not set");
$newp = (isset($_POST['newpword'])) ? $_POST['newpword'] : die("\$_POST['newpword'] is not set");
$user = (isset($_POST['username'])) ? $_POST['username'] : die("\$_POST['username'] is not set");
// you should get the old password, too,
// so you can verify that it's the correct user
$_POST['oldpass'] = 'password';
$oldp = (isset($_POST['oldpass'])) ? $_POST['oldpass'] : die("\$_POST['oldpass'] is not set");
$pdo = new PDO("mysql:host=localhost;dbname=test", 'root', 'password');
$stmt = $pdo->prepare("SELECT password FROM admin WHERE fname=:fname AND username=:user");
$stmt->bindParam(':fname', $name);
$stmt->bindParam(':user', $user);
$success = $stmt->execute();
$result = $stmt->fetch(PDO::FETCH_ASSOC);
if ($success===false) {
print "an error occurred in the query <br/>".print_r($stmt->errorInfo(),true);
}
elseif ($success!==false && $result===false)
{
print "that username was not found in the database";
}
else
{
if ($result['password']==$oldp)
{
$stmt2 = $pdo->prepare("UPDATE admin SET password=:newp where fname=:fname");
/* You should really HASH this password before storing it*/
$stmt2->bindParam(':newp', $newp);
$stmt2->bindParam(':fname', $name);
$success2 = $stmt2->execute();
if ($success2!==false)
{
echo "Password change successfully";
echo"<br>";
echo"<a href=index.php> Click here to signin </a>";
}
else
{
print "an error occurred updating the password <br/>";
}
}
else
{
print "old password didn't match";
}
}
?>
I think the problem is with if($result) condition. Instead of checking $result you should check if(mysql_num_rows($result)>0)
Okay.. I am completely new to this PDO stuff.. I have tried to recreate my mysql script (working) to a PDO script (not working).. I have tested that my DB login informations is correctly programmed for PDO..
This is my PDO script...
<?
session_start();
//connect to DB
require_once("connect.php");
//get the posted values
$email=htmlspecialchars($_POST['email'],ENT_QUOTES);
$pass=md5($_POST['psw']);
//now validating the email and password
$sql - $conn_business->prepare( "SELECT email, password FROM members WHERE email='".$email."'");
$sql -> execute();
$count = $sql->rowCount();
$result = $sql -> fetch();
// Now use $result['rowname'];
$stmt = $conn_business->prepare("SELECT * FROM members WHERE email='".$email."'");
$stmt ->execute();
$act = $stmt -> fetch();
//if email exists
if($count > 0)
{
//compare the password
if(strcmp($result["password"],$pass)==0)
{
// check if activated
if($act["activated"] == "0")
{
echo "act"; //account is not activated yet
}
else
{
echo "yes"; //Logging in
//now set the session from here if needed
$_SESSION['email'] = $email;
}
}
else
echo "no"; //Passwords don't match
}
else
echo "no"; //Invalid Login
?>
And this is my old mysql script...
session_start();
require_once("connect.php");
//get the posted values
$email=htmlspecialchars($_POST['email'],ENT_QUOTES);
$pass=md5($_POST['psw']);
//now validating the username and password
$sql="SELECT email, password members WHERE email='".$email."'";
$result=mysql_query($sql);
$row=mysql_fetch_array($result);
$sql2="SELECT * FROM members WHERE email='".$email."'";
$result2=mysql_query($sql2);
$row2=mysql_fetch_array($result2);
$act = $row2['activated'];
//if username exists
if(mysql_num_rows($result)>0)
{
//compare the password
if(strcmp($row['password'],$pass)==0)
{
// check if activated
if($act == "0")
{
echo "act";
}
else
{
echo "yes";
//now set the session from here if needed
$_SESSION['email'] = $email;
}
}
else
echo "no";
}
else
echo "no"; //Invalid Login
Does anybody know, what I have done wrong? It is an automatically script.. It is called through AJAX and return data based on 'no', 'yes' and 'act' that tells the AJAX/jQuery script what to do.. As I said - the mysql script is working, so please if anyone could tell me what I have done wrong with the PDO script..
EDIT:
when it returns the data to the jQuery script, this should happen:
if yes: start session, redirect to page2.php with session started.
else if act: write in a field that the account is not activated.
else: write that email and password didn't match.
The thing is, that when I try to write the correct e-mail and password - it continues to write : "email and password didn't match" instead of redirecting.. When I say that it is not working it is because the mysql script does as described but the PDO script doesn't..
And I have tried to change the 'echo "no";' to 'echo "yes";' to see if the login would start anyway, but somehow it continues to write that the email and password didn't match..
SOLUTION:
I ahven't told this because I thought it was unnecessary, but the reason for it not to work was because of that i have had my old mysql code in comment marks on top of the page, so that the session_start command didn't work.. After deleting the old code it worked, but then I found something else to change, and that is in the PDO script when it is validating it says:
$sql - $conn_business->prepare( "SELECT email, password FROM members WHERE email='".$email."'");
and then I just changed the '-' after $sql to '=' and now, everything works perfectly... Anyhow thank you everybody.. hope this code can help others..
Did you even read the manual before you "started using" PDO?
That is not how prepared statements are supposed to be used! Your code is filled with SQL injections.
Why are you selecting same row twice ?
The strcmp() is not for checing if one string is identical to another.
And hashing passwords as simple MD5 is just a sick joke.
session_start();
//very stupid way to acquire connection
require_once("connect.php");
//get the posted values
$email = htmlspecialchars($_POST['email'],ENT_QUOTES);
if (filter_var( $email, FILTER_VALIDATE_EMAIL))
{
// posted value is not an email
}
// MD5 is not even remotely secure
$pass = md5($_POST['psw']);
$sql = 'SELECT email, password, activated FROM members WHERE email = :email';
$statement = $conn_business->prepare($sql);
$statement->bindParam(':email', $email, PDO::PARAM_STR);
$output = 'login error';
if ($statement->execute() && $row = $statement->fetch())
{
if ( $row['password'] === $pass )
{
// use account confirmed
if ( $row['activated'] !== 0 ) {
$output = 'not activated';
$_SESSION['email'] = $email;
}
$output = 'logged in';
}
}
echo $output;
i believe the second query in your scripts is not necessary you could simple do
SELECT * FROM members WHERE email=:EMAIL AND password=:PWS;
use bindParam method
$qCredentials->bindParam(":EMAIL",$EMAIL);
$qCredentials->bindParam(":PWS",$PWS);
then do more understable outputs rather than yes or no..
try "Unable to login: Invalid credentials supplied" for invalid types of values or "Unable to login: Invalid credentials, couldn't find user" for invalid user credentials.
You could try to start the session after the user has been successfully logged in your IF condition returning yes, and the methods
$PDOstatement->debugDumpParams()
$PDOstatement->errorInfo()
$PDOstatement->errorCode()
will help you understand what went wrong with a query!