i have been trying to create my own OOPs style register login system in php, i have implemented some security features like xss protection using htmlentites(), prepare method for SQLinjection protection and token based form submission for csrf protection(currently i am stuck implementing this functions in my code, getting "Invalid token" while submitting form data).
But I am not very sure it is good enough for secure site to produce for real live project or not. And i would like you to review my codes, Please help me to solve implementing token base form submission in my code and suggest me the way to improve my coding style in my current code.
This is my register.php page
<?php
//error_reporting(0);
session_start();
if(isset($_POST["submit"])){
include "Db_handlers.php";
$db = new DbHandler();
$res = $db->createUser($_POST["name"], $_POST["email"], $_POST["password"], $_POST["re-password"], $_POST['token']);
print_r($res);
/*if($res){
echo "test";
}
else {
echo $res;
}*/
}
$token = $_SESSION['token'] = md5(uniqid(mt_rand(),true));
?>
<form action="<?=$_SERVER['PHP_SELF'];?>" method="post">
<div class="field">
<label for="name">Name:</label>
<input type="text" name="name" value="" />
</div>
<div class="field">
<label for="email">Email:</label>
<input type="text" name="email" value="" />
</div>
<div class="field">
<label for="password">Password:</label>
<input type="password" name="password" value="" />
</div>
<div class="field">
<label for="repassword">Re-Password:</label>
<input type="password" name="re-password" value="" />
</div>
<input type="hidden" name="token" value="<?=$token;?>"/>
<input type="submit" name="submit" value="submit" />
</form>
This is my DB handler class
<?php
require 'functions.php';
class DbHandler {
private $conn;
public function __construct() {
try{
$this->conn = new PDO("mysql:host=127.0.0.1;dbname=task_manager", "root" , "");
// echo "Connected";
}
catch(PDOException $e){
//die($e->getMessage());
echo "Connection Failed: ".$e->getMessage();
}
}
public function createUser($name, $email, $password, $repassword, $utoken) {
// $error = array();
$error = '';
$required_fields = array($name, $email, $password, $repassword);
$fields = array_map('trim', $required_fields);
if (in_array(null, $fields)) {
$error = 'Fields marked with an asterisk are required';
}
else if($this->valid_token($utoken) == false){
$error = "Invalid Token...!!!";
}
else if(!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$error = 'Please enter a valid email address !';
}
else if(strlen($password) < 6){
$error = "Password must be atleast 6 characters";
}
else if($password !== $repassword){
$error = "Password do n\' t match!!";
}
else{
$name = escape($name);
$email = escape($email);
$password_hash = escape($password);
// First check if user already existed in db
if (!$this->isUserExists($email)) {
// Generating password hash
$password_hash = password_hash($password, PASSWORD_DEFAULT, ['cost'=>12]);
// insert query
$stmt = $this->conn->prepare("INSERT INTO users(name, email, password_hash, status) values(:name, :email, :password_hash, 1)");
//$stmt->bind_param("ssss", $name, $email, $password_hash);
$result = $stmt->execute(array(':name' => $name,':email' => $email,':password_hash' => $password_hash));;
//$stmt->close();
// Check for successful insertion
if ($result) {
// User successfully inserted
return $result;
} else {
// Failed to create user
$error = "Failed to create user";
}
} else {
// User with same email already existed in the db
$error = "User already exists";
}
}
return $error;
}
private function isUserExists($email) {
$stmt = $this->conn->prepare("SELECT id from users WHERE email = :email");
//$stmt->bind_param("s", $email);
$stmt->execute(array(':email' => $email));
//$stmt->bind_result();
$num_rows = $stmt->rowCount();
//$stmt->close();
return $num_rows > 0;
}
public function valid_token($token){
if(!isset($_SESSION['token']) || $token != $_SESSION['token'])
return false;
}
}
Your code is really hard to read... You should indent it properly.
Back to your question. It seems, you just return false, if your token is incorrect, but your forget to return true, if it is correct. If your return nothing, you implicitly return null, which evaluates to false. I guess, your code works, if your change valid_token like this:
public function valid_token($token){
return isset($_SESSION['token']) && $token == $_SESSION['token'];
}
Im trying to sign in with PDO but I cant. When I'm trying with old database connection it works, but with PDO its not; I cant understand where exactly is the issue, connection is OK but the code is not navigating to other page, Email and passwords are correct.Please see the mail below and if you can help me.
<?php
$servername = "localhost";
$username = "root";
$password = "";
try {
$conn = new PDO("mysql:host=$servername;dbname=social", $username, $password);
// set the PDO error mode to exception
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
//echo "Connected successfully";
}
catch(PDOException $e)
{
echo "Connection failed: " . $e->getMessage();
}
class UserLogin {
public $id;
public $first;
public $last;
public $email;
public $password;
function Login(){
global $conn;
$this->email = $_POST['user_email'];
$this->password = $_POST['user_email'];
$sql = $conn->prepare("SELECT * FROM scusers WHERE scemail =? AND scpass =?");
$sql->execute(array($this->email, $this->password));
while($row = $sql->fetch(PDO::FETCH_ASSOC)){
$this->email = $row['scemail'];
$this->password = $row['scpass'];
}
}
}
<?php
//print_r($_POST);
if(isset($_POST['user_email']) && isset($_POST['user_password'])){
$login = new UserLogin();
$login->email = $_POST['user_email'];
$login->password = $_POST['user_password'];
if($login->Login()){
header("Location:home.php");
}else{
echo "Negative";
}
}
?>
<body>
<header>
<form action="#" method="post">
<div class="col-sm-6">
<div class="row">
<div class="col-sm-5">
<div class="form-group">
<input name="user_email" type="text" class="form-control" placeholder="Email Address">
<div class="login-bottom-text checkbox">
<label>
<input type="checkbox" id="">
</label>
</div>
</div>
</div>
<div class="col-sm-5">
<div class="form-group">
<input name="user_password" type="text" class="form-control" placeholder="Password">
<div class="login-bottom-text"><a class="bottom-txt" href="recover_password.php">Forgot your password?</a></div>
</div>
</div>
<div class="col-sm-2">
<div class="form-group">
<button type="submit" value=" Send" class="btn btn-default" id="submit">login</button>
</div>
</div>
</div>
</div>
</form>
This code block will always echo 'Negative' because method Login doesn't return anything
if($login->Login()){
header("Location:home.php");
}else{
echo "Negative";
}
It should return true in case of finding a row in the database.
Login() method has no return statement. Without return statement function returns NULL. NULL is obvioulsy considered falsy. So, change Login() method so it returns some truthy value, at least this way:
function Login(){
$user_found = false;
global $conn;
$this->email = $_POST['user_email'];
$this->password = $_POST['user_email']; // is it?
$sql = $conn->prepare("SELECT * FROM scusers WHERE scemail =? AND scpass =?");
$sql->execute(array($this->email, $this->password));
while ($row = $sql->fetch(PDO::FETCH_ASSOC)){
$this->email = $row['scemail'];
$this->password = $row['scpass'];
$user_found = true;
}
return $user_found;
}
i am using below code for customer Registration & Login , it's working fine.
db connection
<?php
class Database
{
private $host = "localhost";
private $db_name = "dbname";
private $username = "root";
private $password = "helpme";
public $conn;
public function dbConnection()
{
$this->conn = null;
try
{
$this->conn = new PDO("mysql:host=" . $this->host . ";dbname=" . $this->db_name, $this->username, $this->password);
$this->conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $exception)
{
echo "Connection error: " . $exception->getMessage();
}
return $this->conn;
}
}
?>
register
<?php
session_start();
require_once 'class.user.php';
$reg_user = new USER();
if($reg_user->is_logged_in()!="")
{
$reg_user->redirect('home.php');
}
if(isset($_POST['btn-signup']))
{
$uname = trim($_POST['txtuname']);
$email = trim($_POST['txtemail']);
$upass = trim($_POST['txtpass']);
$cpass = trim($_POST['txtcpass']);
$phone = trim($_POST['phone']);
$street_address = trim($_POST['street_address']);
$street_address_2 = trim($_POST['street_address_2']);
$city = trim($_POST['city']);
$state = trim($_POST['state']);
$zip_code = trim($_POST['zip_code']);
$country = trim($_POST['country']);
$code = md5(uniqid(rand()));
$stmt = $reg_user->runQuery("SELECT * FROM tbl_users WHERE userEmail=:email_id");
$stmt->execute(array(":email_id"=>$email));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if($stmt->rowCount() > 0)
{
$msg = "
<div class='alert alert-error'>
<button class='close' data-dismiss='alert'>×</button>
<strong>Sorry !</strong> email allready exists , Please Try another one
</div>
";
}
if($upass != $cpass){
$msg = "passwords doesn't match";
}
else
{
if($reg_user->register($uname,$email,$upass, $code, $phone, $street_address, $street_address_2 , $city , $state , $zip_code , $country ))
{
$id = $reg_user->lasdID();
$key = base64_encode($id);
$id = $key;
$message = "
Hello $uname,
<br /><br />
Welcome to designer!<br/>
To complete your registration please , just click following link<br/>
<br /><br />
<a href='http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]'.'verify.php?id=$id&code=$code'>Click HERE to Activate :)</a>
<br /><br />
Thanks,";
$subject = "Confirm Registration";
$reg_user->send_mail($email,$message,$subject);
$msg = "
<div class='alert alert-success'>
<button class='close' data-dismiss='alert'>×</button>
<strong>Success!</strong> We've sent an email to $email.
Please click on the confirmation link in the email to create your account.
</div>
";
}
else
{
echo "sorry , Query could no execute...";
}
}
}
?>
<!DOCTYPE html>
<html>
<head>
</head>
<body id="login">
<div class="container">
<?php if(isset($msg)) echo $msg; ?>
<form class="form-signin" method="post">
<h2 class="form-signin-heading">Sign Up</h2><hr />
<input type="text" class="input-block-level" placeholder="Username" name="txtuname" required />
<input type="email" class="input-block-level" placeholder="Email address" name="txtemail" required />
<input id="pass1" type="password" class="input-block-level" placeholder="Password" name="txtpass" required />
<input id="pass2" type="password" class="input-block-level" placeholder="confirm Password" name="txtcpass" required />
<input type="text" class="input-block-level" placeholder="Telephone" name="phone" />
<input type="text" class="input-block-level" placeholder="Street Address" name="street_address" />
<input type="text" class="input-block-level" placeholder="Stree Address 2" name="street_address_2" />
<input type="text" class="input-block-level" placeholder="city" name="city" />
<input type="text" class="input-block-level" placeholder="state" name="state" />
<input type="text" class="input-block-level" placeholder="zip code" name="zip_code" />
<input type="text" class="input-block-level" placeholder="country" name="country" />
<hr />
<input class="btn btn-large btn-primary" name="btn-signup" type="submit" id="btnSubmit" value="Sign Up" onclick="return comparePasswords()" />
Sign In
</form>
</div> <!-- /container -->
<script src="vendors/jquery-1.9.1.min.js"></script>
<script src="bootstrap/js/bootstrap.min.js"></script>
</body>
</html>
class.user.php
<?php
require_once 'dbconfig.php';
class USER
{
private $conn;
public function __construct()
{
$database = new Database();
$db = $database->dbConnection();
$this->conn = $db;
}
public function runQuery($sql)
{
$stmt = $this->conn->prepare($sql);
return $stmt;
}
public function lasdID()
{
$stmt = $this->conn->lastInsertId();
return $stmt;
}
public function register($uname,$email,$upass, $code, $phone, $street_address, $street_address_2 , $city , $state , $zip_code , $country)
{
try
{
$password = md5($upass);
$stmt = $this->conn->prepare("INSERT INTO tbl_users(userName,userEmail,userPass, tokenCode, phone, street_address, street_address_2 , city , state , zip_code , country)
VALUES(:user_name, :user_mail, :user_pass, :active_code, :phone , :street_address, :street_address_2 , :city , :state , :zip_code , :country)");
$stmt->bindparam(":user_name",$uname);
$stmt->bindparam(":user_mail",$email);
$stmt->bindparam(":user_pass",$password);
$stmt->bindparam(":active_code",$code);
$stmt->bindparam(":phone",$phone);
$stmt->bindparam(":street_address",$street_address);
$stmt->bindparam(":street_address_2",$street_address_2);
$stmt->bindparam(":city",$city);
$stmt->bindparam(":state",$state);
$stmt->bindparam(":zip_code",$zip_code);
$stmt->bindparam(":country",$country);
$stmt->execute();
return $stmt;
}
catch(PDOException $ex)
{
echo $ex->getMessage();
}
}
public function login($email,$upass)
{
try
{
$stmt = $this->conn->prepare("SELECT * FROM tbl_users WHERE userEmail=:email_id");
$stmt->execute(array(":email_id"=>$email));
$userRow=$stmt->fetch(PDO::FETCH_ASSOC);
if($stmt->rowCount() == 1)
{
if($userRow['userStatus']=="Y")
{
if($userRow['userPass']==md5($upass))
{
$_SESSION['userSession'] = $userRow['userID'];
return true;
}
else
{
header("Location: index.php?error");
exit;
}
}
else
{
header("Location: index.php?inactive");
exit;
}
}
else
{
header("Location: index.php?error");
exit;
}
}
catch(PDOException $ex)
{
echo $ex->getMessage();
}
}
public function is_logged_in()
{
if(isset($_SESSION['userSession']))
{
return true;
}
}
public function redirect($url)
{
header("Location: $url");
}
}
home.php [ customer will redirect to this home/profile page after login]
<?php
//Initializing variable
session_start();
require_once 'class.user.php';
$user_home = new USER();
if(!$user_home->is_logged_in())
{
$user_home->redirect('index.php');
}
$stmt = $user_home->runQuery("SELECT * FROM tbl_users WHERE userID=:uid");
$stmt->execute(array(":uid"=>$_SESSION['userSession']));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
?>
in registration page we have name, email, city, zip....etc.
i need to provide an option for customer to update those fields in profile page.
once customer login, he will be redirect to profile/home page, in that page
I want to display all form fields and provide a "edit" button and once he click on that button, he should be able to update the values of name, email....etc.
i tried by adding below code, but not working for me.
class.user.php
public function update($uname,$email,$phone) {
try {
$stmt = $this->_db->prepare('UPDATE tbl_users SET userName = ?, userEmail = ?, phone = ? WHERE userID = ? ');
$stmt->execute(array($uname,$email,$phone,$_SESSION['userID']));
return $stmt->fetch();
} catch(PDOException $e) {
echo '<p class="bg-danger">'.$e->getMessage().'</p>';
}
}
home or profile [home.php ]
$FORM['uname'] = "";
$FORM['txtuname'] = "";
if (isset($_POST['submit'])) {
// new data
$uname = $_POST['txtuname'];
$email = $_POST['txtemail'];
$phone = $_POST['phone'];
$uid = (isset($_GET['userID']) ? intval($_GET['userID']) : -1);
// query
if ($uid->update($uname,$email,$phone,$userID)); {
redirect('home.php');
}
}
<form action="home.php" method="POST">
Name<br>
<input type="text" name="txtuname" value="<?php echo $_SESSION['txtuname'] ?>" /><br>
Email<br>
<input type="text" name="txtemail" value="<?php echo $_SESSION['email'] ?>" /><br>
Phone<br>
<input type="text" name="phone" value="<?php echo $_SESSION['phone'] ?>" /><br>
<input type="submit" name="submit" value="Save" />
</form>
its giving error : Fatal error: Call to a member function update() on a non-object in line
if ($uid->update($uname,$email,$phone,$userID)); {
$uid is not an user object, so you can not call update on it.
You should first retrieve the user object identified by its id from the database und then call update on it.
Additionally, you've got an error in class.user.php:
$stmt = $this->_db->prepare('UPDATE tbl_users SET userName = ?, userEmail = ?, phone = ? WHERE userID = ? ');
should be:
$stmt = $this->conn->prepare('UPDATE tbl_users SET userName = ?, userEmail = ?, phone = ? WHERE userID = ? ');
then in home.php you could do something like this:
$user_home = new USER();
// query
if ($user_home->update($uname,$email,$phone,$uid)); {
$user_home->redirect('home.php');
}
Another issue is, that you assign the users id to $_SESSION['userSession'] so you have to change your update function in your class.user.php:
public function update($uname,$email,$phone) {
try {
$stmt = $this->conn->prepare('UPDATE tbl_users SET userName = ?, userEmail = ?, phone = ? WHERE userID = ? ');
$stmt->execute(array($uname,$email,$phone,$_SESSION['userSession']));
return $stmt->fetch();
} catch(PDOException $e) {
echo '<p class="bg-danger">'.$e->getMessage().'</p>';
}
}
And finally (because you are currently not saving the users email etc. in the session) the form on the bottom of home.php should look rather like this (now including an edit button):
<script>function toggle() { var can = document.getElementsByName("submit"); for (i = 0; i < can.length; i++) { can[i].style.display = can[i].style.display === 'none' ? 'block' : 'none'; }}</script>
<form action="home.php" method="POST">
Name<br>
<input type="text" name="txtuname" value="<?php echo $row['userName'] ?>" /><br>
Email<br>
<input type="text" name="txtemail" value="<?php echo $row['userEmail'] ?>" /><br>
Phone<br>
<input type="text" name="phone" value="<?php echo $row['phone'] ?>" /><br>
<input id="sub" type="submit" name="submit" value="Save" style="display:none" />
</form>
<button name="submit" onclick="toggle()">Edit</button>
</html>
Based on your code, $uid is an integer, either -1 or the userID GET parameter.
Probably you wanted something like
$user_home->update( ..., $uid );
instead, assuming $user_home = new USER(); is missing. Or maybe any other instance of USER has to be created
$another = new USER();
...
$another->update( ..., $uid );
Why are you storing all your user info in a Session. User id or user name should be passed in a get variable. You then validate it that it exist if it doesn't no need to keep going kill the script. Redirect to error page or something. Also user should only be allowed to edit if user_id from the session equals get user_id, that means that user visiting current page. Is the owner so he can modify it. The value in your form should be the results from the database. Also you have no email or text input validation. Like a check that makes sure its a real email. A check to make sure text is only letters and numbers when form is submitted.
As far as your error, Where did you declare your object? I don't see it.
it has to be something like this.
$user_home = new USER();
then you can call update like so
$uid = $user_home->update($uname,$email,$phone,$userID);
you have an error here
public function update($uname,$email,$phone) { try { $stmt = $this->_db->prepare('UPDATE tbl_users SET userName = ?, userEmail = ?, phone = ? WHERE userID = ? '); $stmt->execute(array($uname,$email,$phone,$_SESSION['userID'])); return $stmt->fetch(); } catch(PDOException $e) { echo '<p class="bg-danger">'.$e->getMessage().'</p>'; } }
remove the _ from db like this
$stmt = $this->db->prepare('UPDATE tbl_users SET userName = ?, userEmail = ?, phone = ? WHERE userID = ? '
I think i have a quick workaround for your problem, based on the example you have provided and the fact that you might not need to re-write too much code. This is your home.php page
<?php
//Initializing variable
session_start();
require_once 'class.user.php';
$user_home = new USER();
if(!$user_home->is_logged_in())
{
$user_home->redirect('index.php');
}
$stmt = $user_home->runQuery("SELECT * FROM tbl_users WHERE userID=:uid");
$stmt->execute(array(":uid"=>$_SESSION['userSession']));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
?>
Rewrite it like this
<?php
//Initializing variable
session_start();
require_once 'class.user.php';
$user_home = new USER();
// Fetch user from database based on user id
$stmt = $user_home->runQuery("SELECT * FROM tbl_users WHERE userID=:uid");
$stmt->execute(array(":uid"=>$_SESSION['userSession']));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
// $row will provide the old values stored in database if you want them to be displayed as initial values inside your input fields
if(!$user_home->is_logged_in())
{
$user_home->redirect('index.php');
} else {
// adding this here ensures that the $user_home object exists
require_once("profile.php");
}
?>
Then your profile.php page can be like this simple example.
if (isset($_POST['submit'])) {
// new data
$uname = $_POST['txtuname'];
$email = $_POST['txtemail'];
$phone = $_POST['phone'];
$userID= $row['userID'];
// query
$user_home->update($uname,$email,$phone,$userID));
}
<form action="" method="POST">
Name<br>
<input type="text" name="txtuname" value="<?php echo $row['userName'] ?>" /><br>
Email<br>
<input type="text" name="txtemail" value="<?php echo $row['userEmail'] ?>" /><br>
Phone<br>
<input type="text" name="phone" value="<?php echo $row['userPhone'] ?>" /><br>
<input type="submit" name="submit" value="Save" />
</form>
I have found one tutorial for login/register form in google. The problem is that I can't understand how to work with sessions and especially how to use the ID of logged user. So this is the login form.
<form id="login-form" action="login.php" method="post" role="form" style="display: block;">
<div class="form-group">
<input type="text" name="username" id="username" class="form-control input-lg" placeholder="Потребителско име" value="<?php if(isset($error)){ echo $_POST['username']; } ?>" tabindex="1">
</div>
<div class="form-group">
<input type="password" name="password" id="password" class="form-control input-lg" placeholder="Парола" tabindex="3">
</div>
<div class="row">
<div class="col-xs-6 col-md-6"><input type="submit" name="submit" value="Log" class="btn btn-primary btn-block btn-lg" tabindex="5">
</div>
</div>
</form>
Login.php
//check if already logged in move to home page
if( $user->is_logged_in() ){ header('Location: userAction.php'); }
//process login form if submitted
if(isset($_POST['submit'])){
$username = $_POST['username'];
$password = $_POST['password'];
if($user->login($username,$password,$id)){
$_SESSION['username'] = $username;
header('Location: index.php');
exit;
} else {
header('Location: userAction.php');
$_SESSION['errMsg'] = 'Wrong username/password';
}
}
And this is the user class
class User extends Password{
private $_db;
function __construct($pdo){
parent::__construct();
$this->_db = $pdo;
}
private function get_user_hash($username){
try {
$stmt = $this->_db->prepare('SELECT password FROM users WHERE username = :username AND active="Yes" ');
$stmt->execute(array('username' => $username));
$row = $stmt->fetch();
return $row['password'];
} catch(PDOException $e) {
echo '<p class="bg-danger">'.$e->getMessage().'</p>';
}
}
public function login($username,$password){
$hashed = $this->get_user_hash($username);
if($this->password_verify($password,$hashed) == 1){
$_SESSION['loggedin'] = true;
return true;
}
}
public function logout(){
session_destroy();
}
public function is_logged_in(){
if(isset($_SESSION['loggedin']) && $_SESSION['loggedin'] == true){
return true;
}
}
}
So everything work just fine. I can register and login without any problems. Also I can call $_SESSION['username'] whenever I want but I want to use also userid with $_SESSION['userid']..
May be is something easy but can't understand what and where I should put.
Edit:
This is how they look now: user.php
public function login_user_id($username){
try {
$stmt = $this->_db->prepare('SELECT id,email FROM users WHERE username = :username');
$stmt->execute(array('username' => $username));
// $row = $stmt->fetch();
return $row = $stmt->fetch();
} catch(PDOException $e) {
echo '<p class="bg-danger">'.$e->getMessage().'</p>';
}
}
and this is the login.php
if($user->login($username,$password)){
$data=$user->login_user_id($username);
foreach($data as $row)
{
$row['id'] = $_SESSION['id'];// assing user_id to session
$row['email'] = $_SESSION['email'];
}
$_SESSION['username'] = $username;
header('Location: index.php');
exit;
}
After matching password you need to get the id of logging user's
if($user->login($username,$password)){
$user_id=$user->login_user_id($username);// get user id
$_SESSION['user_id'] = $user_id;// assing user_id to session
$_SESSION['username'] = $username;
header('Location: index.php');
exit;
}
Getting user_id according to username from database
function login_user_id($username){
try {
$stmt = $this->_db->prepare('SELECT user_id FROM users WHERE username = :username');
$stmt->execute(array('username' => $username));
$row = $stmt->fetch();
return $row['user_id'];
} catch(PDOException $e) {
echo '<p class="bg-danger">'.$e->getMessage().'</p>';
}
}
You need to chang two functions
private function get_user_hash($username){
try {
$stmt = $this->_db->prepare('SELECT password,id FROM users WHERE username = :username AND active="Yes" ');
$stmt->execute(array('username' => $username));
$row = $stmt->fetch();
return $row;
} catch(PDOException $e) {
echo '<p class="bg-danger">'.$e->getMessage().'</p>';
}
}
public function login($username,$password){
$hashed = $this->get_user_hash($username);
if($this->password_verify($password,$hashed['password']) == 1){
$_SESSION['loggedin'] = true;
$_SESSION['userid'] = $hashed['id'];
return true;
}
}
I have login/register form which are working perfectly. Now I'm trying to make script to allow user to change password but I can't understand why doesn't work. This is the HTML form
<form action="editAccount.php" method="post">
<div class="input-group">
<span class="input-group-addon">Password:</span>
<input type="password" name="password" class="form-control" placeholder="password">
</div>
<button class="btn btn-primary custom-button btn-block" type="submit"><i class="fa fa-check"></i> Save Changes</button>
<div class="input-group">
<span class="input-group-addon">Confirm password:</span>
<input type="password" name="passwordConfirm" class="form-control" placeholder="Confirm password">
</div>
</form>
And this is the PHP part
if(empty($_SESSION['id']))
{
header("Location: userAction.php");
die("Redirecting to userAction.php");
}
if(isset($_POST['submit']))
{
//basic validation
if(strlen($_POST['password']) < 3){
$error[] = 'Password is too short.';
}
if(strlen($_POST['passwordConfirm']) < 3){
$error[] = 'Confirm Password is too short.';
}
if($_POST['password'] != $_POST['passwordConfirm']){
$error[] = 'Password and Confirm password doesn't match.';
}
if(empty($error)){
$hashedpassword = $user->password_hash($_POST['password'], PASSWORD_BCRYPT);
try {
$stmt = $pdo->prepare("UPDATE users SET password = :hashedpassword WHERE id = :user_id");
$stmt->execute(array(
':hashedpassword' => $hashedpassword,
':user_id' => $_SESSION['id']
));
header('Location: userAction.php?action=joined');
exit;
} catch(PDOException $e)
{
$error[] = $e->getMessage();
}
}
}
On var_dump($_POST['password'] result is - string(11) "newpassword" i.e. POST got the password.
On var_dump($hashedpassword) result is - NULL. So the problem must be in hashing function.
Here is also what I have in $user
class User extends Password{
private $_db;
function __construct($pdo){
parent::__construct();
$this->_db = $pdo;
}
private function get_user_hash($username){
try {
$stmt = $this->_db->prepare('SELECT password FROM users WHERE username = :username AND active="Yes" ');
$stmt->execute(array('username' => $username));
$row = $stmt->fetch();
return $row['password'];
} catch(PDOException $e) {
echo '<p class="bg-danger">'.$e->getMessage().'</p>';
}
}
public function login($username,$password){
$hashed = $this->get_user_hash($username);
if($this->password_verify($password,$hashed) == 1){
$_SESSION['loggedin'] = true;
return true;
}
}
public function login_user_id($username){
try {
$stmt = $this->_db->prepare('SELECT id FROM users WHERE username = :username');
$stmt->execute(array('username' => $username));
$row = $stmt->fetch();
return $row['id'];
} catch(PDOException $e) {
echo '<p class="bg-danger">'.$e->getMessage().'</p>';
}
}
public function logout(){
session_destroy();
}
public function is_logged_in(){
if(isset($_SESSION['loggedin']) && $_SESSION['loggedin'] == true){
return true;
}
}
}
As you told in comments, it doesn't even enter into the if(isset($_POST['submit'])) { part, because you don't have an input named "submit".
Try it with an <input type="submit" name="submit"> or a hidden input named "submit".