Change password script with BCRYPT - php

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".

Related

How to fix PHP saying boxes are empty

PHP saying theres nothing in the boxes when I put stuff in.
Tried putting var_dump($_POST); die(); at the top of register.php and it showed what I put in the boxes
Not sure what's going on here.
Any help is appreciated. Thanks in advance.
I've spent a while trying to figure this out.
Will login work aswell?
Thanks,
Jon
functions.php
<?php
session_start();
// connect to database
$db = mysqli_connect(:-));
// variable declaration
$username = "";
$email = "";
$errors = array();
// call the register() function if register_btn is clicked
if (isset($_POST['register_btn'])) {
register();
}
// REGISTER USER
function register(){
// call these variables with the global keyword to make them available in function
global $db, $errors, $username, $email;
// receive all input values from the form. Call the e() function
// defined below to escape form values
$username = e($_POST['username']);
$email = e($_POST['email']);
$password_1 = e($_POST['password_1']);
$password_2 = e($_POST['password_2']);
// form validation: ensure that the form is correctly filled
if (empty($username)) {
array_push($errors, "Username is required");
}
if (empty($email)) {
array_push($errors, "Email is required");
}
if (empty($password_1)) {
array_push($errors, "Password is required");
}
if ($password_1 != $password_2) {
array_push($errors, "The two passwords do not match");
}
// register user if there are no errors in the form
if (count($errors) == 0) {
$password = md5($password_1);//encrypt the password before saving in the database
if (isset($_POST['user_type'])) {
$user_type = e($_POST['user_type']);
$query = "INSERT INTO users (username, email, user_type, password)
VALUES('$username', '$email', '$user_type', '$password')";
mysqli_query($db, $query);
$_SESSION['success'] = "New user successfully created!!";
header('location: home.php');
}else{
$query = "INSERT INTO users (username, email, user_type, password)
VALUES('$username', '$email', 'user', '$password')";
mysqli_query($db, $query);
// get id of the created user
$logged_in_user_id = mysqli_insert_id($db);
$_SESSION['user'] = getUserById($logged_in_user_id); // put logged in user in session
$_SESSION['success'] = "You are now logged in";
header('location: index.php');
}
}
}
// return user array from their id
function getUserById($id){
global $db;
$query = "SELECT * FROM users WHERE id=" . $id;
$result = mysqli_query($db, $query);
$user = mysqli_fetch_assoc($result);
return $user;
}
// escape string
function e($val){
global $db;
return mysqli_real_escape_string($db, trim($val));
}
function display_error() {
global $errors;
if (count($errors) > 0){
echo '<div class="error">';
foreach ($errors as $error){
echo $error .'<br>';
}
echo '</div>';
}
}
function isLoggedIn()
{
if (isset($_SESSION['user'])) {
return true;
}else{
return false;
}
}
if (isset($_GET['logout'])) {
session_destroy();
unset($_SESSION['user']);
header("location: login.php");
}
if (isset($_POST['login_btn'])) {
login();
}
// LOGIN USER
function login(){
global $db, $username, $errors;
// grap form values
$username = e($_POST['username']);
$password = e($_POST['password']);
// make sure form is filled properly
if (empty($username)) {
array_push($errors, "Username is required");
}
if (empty($password)) {
array_push($errors, "Password is required");
}
// attempt login if no errors on form
if (count($errors) == 0) {
$password = md5($password);
$query = "SELECT * FROM users WHERE username='$username' AND password='$password' LIMIT 1";
$results = mysqli_query($db, $query);
if (mysqli_num_rows($results) == 1) { // user found
// check if user is admin or user
$logged_in_user = mysqli_fetch_assoc($results);
if ($logged_in_user['user_type'] == 'admin') {
$_SESSION['user'] = $logged_in_user;
$_SESSION['success'] = "You are now logged in";
header('location: admin/home.php');
}else{
$_SESSION['user'] = $logged_in_user;
$_SESSION['success'] = "You are now logged in";
header('location: index.php');
}
}else {
array_push($errors, "Wrong username/password combination");
}
}
}
// ...
function isAdmin()
{
if (isset($_SESSION['user']) && $_SESSION['user']['user_type'] == 'admin' ) {
return true;
}else{
return false;
}
}
register.php
<?php
include('functions.php');
?>
<!DOCTYPE html>
<html>
<head>
<title>Register | Vex Radio</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="header">
<h2>Register</h2>
</div>
<form method="post" action="register.php">
<p><?php echo display_error(); ?></p>
<div class="input-group">
<label>Username</label>
<input type="text" name="username" value="<?php echo $username; ?>">
</div>
<div class="input-group">
<label>Email</label>
<input type="email" name="email" value="<?php echo $email; ?>">
</div>
<div class="input-group">
<label>Password</label>
<input type="password" name="password_1">
</div>
<div class="input-group">
<label>Confirm password</label>
<input type="password" name="password_2">
</div>
<div class="input-group">
<button type="submit" class="btn" name="register_btn">Register</button>
</div>
<p>
Already a member? Sign in
</p>
</form>
</body>
</html>
PHP to save the items in a DB and allow me to login

Login form doesn't verify the password

I am working on a login form and the password doesn't get verified from some reason. The user supposed to log in into system with email and password. I am matching user based on the email with the data in database. Could you please look at it?
Customer table
HTML form in file index.php
<div id="test-popup" class="white-popup mfp-hide col-sm-4 col-sm-offset-4 col-xs-10 col-xs-offset-1 align-center">
<img src="images/logo-white.png" alt="" height="120px" width="120px" />
<h5 class="font-alt">Login to Your Account</h5>
<br/>
<form method="post" action="login.php" class="form">
<div class="mb-20 mb-md-10">
<input type="text" name="email" id="email" class="input-md form-control" placeholder="Email" required />
</div>
<div class="mb-20 mb-md-10">
<input type="password" name="password" id="password" class="input-md form-control" placeholder="Password" required />
</div>
<div class="mb-20 mb-md-10">
<input type="submit" name="login" class="login btn btn-mod btn-medium" id="btnLogIn" value="Login" />
</div>
</form>
</div>
File login.php
<?php
require_once 'connection_db.php';
$response = new stdClass;
if (empty($_POST['email']) || empty($_POST['password'])) {
$response->success = false;
$response->message = 'Email and password cannot be empty.';
} else {
$sql = 'SELECT * FROM `customer` WHERE `email` = ? ';
$email = $_POST['email'];
$password = $_POST['password'];
$password = password_hash($password, PASSWORD_DEFAULT);
// print_r($password, true);
try {
$stmt = $db->prepare($sql);
$stmt->bind_param('s', $email);
$stmt->execute();
$result = $stmt->get_result();
$array = $result->fetch_array(MYSQLI_ASSOC);
// print_r($array, true);
if (count($array)) {
$response->success = true;
$response->message = 'Login successful.';
session_start();
$_SESSION['email'] = $email;
$_SESSION['id'] = $id;
$_SESSION['current_page'] = $_SERVER['HTTP_REFERER'];
header("Location: ". $_SESSION['current_page']);
} else {
$response->success = false;
$response->message = 'Wrong username or password.';
header("Location: index.php#test-popup");
}
}
catch (Exception $e) {
$response->success = false;
$response->message = "Error.";
}
}
// unset($db);
?>
Here's a generic setup of how your login script should look:
if (isset($_POST['submit']))
{
$email = $_POST['email'];
$password = $_POST['password'];
if (!empty($email) && !empty($password))
{
$res = $dbh->prepare("SELECT * FROM `customer` WHERE `email` = ?");
$res->execute([$email]);
$row = $res->fetch(MYSQLI_ASSOC);
if ($res->rowCount() > 0)
{
if (password_verify($password, $row['password']))
{
$_SESSION['user_session'] = $row['uid'];
header('Location: loggedIn.php');
} else {
// echo incorrect pass
}
} else {
// echo no such user...
}
} else {
// echo something...
}
}
You should be using password_verify for your login script. You only use password_hash for registering to hash the password that has been submitted.

how to implement token base form submission in php

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'];
}

Using ID in session after successful login

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;
}
}

User class and form update PDO

I have created this form to update the data of the various user profiles. The update works but I would need some tricks and aid. The form is really minimal, reduced to essentials, I was wondering how to improve it, perhaps placing the controls to make it as safe as possible, how can I do?
Also, I can not take the id of the user via the SESSION, other data picks them up, as a location, but the email ID no. So I'll need just because the form has to be based of course the ID of the user. I was wondering if invede of SESSIONS, it was not better to create a class that collects user data, for example: $user['email'];
However, I paste the class user.php
include('password.php');
class User extends Password{
private $_db;
function __construct($db){
parent::__construct();
$this->_db = $db;
}
private function get_user_hash($username){
try {
$stmt = $this->_db->prepare('SELECT password FROM members 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;
}
}
public function is_logged_admin(){
if(isset($_SESSION['level']) && $_SESSION['level'] == 2 ) {
return true;
}
return false;
}
public function get_user_info($username){
try {
$stmt = $this->_db->prepare('SELECT memberID,email,location,gender,level,active FROM members WHERE username = ?');
$stmt->execute(array($username));
return $stmt->fetch();
} catch(PDOException $e) {
echo '<p class="bg-danger">'.$e->getMessage().'</p>';
}
}
}
and the form that I called account.php
<form role="form" method="POST">
<div class="form-group">
<label class="control-label">Email</label>
<input type="text" name="email" class="form-control" value="<?= $_SESSION['email']; ?>">
</div>
<div class="form-group">
<label class="control-label">Location</label>
<input type="text" name="location" class="form-control" value="<?= $_SESSION['location']; ?>">
</div>
<div class="form-group">
<label class="control-label">Gender</label>
<input type="text" name="gender" class="form-control" value="<?= $_SESSION['gender']; ?>">
</div>
<div class="margiv-top-10">
<input type="submit" name="submit" class="btn" value="Update">
</div>
</form>
And,
if (isset($_POST['email'], $_POST['location'], $_POST['gender'])) {
$stmt = $db->prepare("UPDATE members SET email = ?, location = ?, gender = ? WHERE memberID = 1");
$stmt->execute([$_POST['email'], $_POST['location'], $_POST['gender']]);
}

Categories