im going to insane here, why he jump to else and return false all the time.
i dont understand what im doing wrong.
try
{
$query = 'SELECT userID, firstname, surname, email FROM jinx_users WHERE email = :email AND password = :password';
$this->dbh->beginTransaction();
$stmt = $this->dbh->prepare($query);
$stmt->bindParam(':email', $email, PDO::PARAM_STR);
$stmt->bindParam(':password', $password, PDO::PARAM_STR);
$stmt->execute();
if($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
return true;
}else{
return false;
}
$stmt = null;
}
catch (Exception $e)
{
$stmt = null;
$this->dbh->rollback();
exit();
}
The if statement is not a valid statement. Apart from that the Try Catch should be used to check if the database can succesfully be called or params can be set etc. Inside a try/catch you want to avoid return true or false. So with that being said I think what you want is the following:
try {
$query = 'SELECT userID, firstname, surname, email FROM jinx_users WHERE email = :email AND password = :password';
$this->dbh->beginTransaction();
$stmt = $this->dbh->prepare($query);
$stmt->bindParam(':email', $email, PDO::PARAM_STR);
$stmt->bindParam(':password', $password, PDO::PARAM_STR);
$stmt->execute();
} catch (Exception $e) {
var_dump($e->getMessage();
die();
}
if($stmt->fetch(PDO::FETCH_ASSOC)) {
return true;
} else {
return false;
}
Related
The password is hashed and enters the db when i try to verify it it returns false every time i have echoed out the password going in and the db password the column in the database is the correct size
<?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 register($uname, $umail, $upass)
{
try
{
$new_password = password_hash($upass, PASSWORD_DEFAULT);
$stmt = $this->conn->prepare("INSERT INTO USERS(USERNAME, EMAIL, PASSWORD) VALUES(:uname, :umail, :upass)");
$stmt->bindparam(":uname", $uname);
$stmt->bindparam(":umail", $umail);
$stmt->bindparam(":upass", $new_password);
$stmt->execute();
return $stmt;
}
catch(PDOException $e)
{
echo $e->getMessage();
}
}
public function doLogin($uname, $umail, $upass)
{
try
{
$stmt = "SELECT USERID, USERNAME, EMAIL, PASSWORD, FIRSTNAME FROM USERS WHERE USERNAME = :uname OR EMAIL = :umail ";
$stmt = $this->conn->prepare($stmt, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL));
$stmt->bindparam(':uname', $uname);
$stmt->bindparam(':umail', $umail);
$stmt->execute();
$userRow = $stmt->fetch(PDO::FETCH_ASSOC);
$db_password = $userRow['PASSWORD'];
$sql = "SELECT COUNT(*) FROM USERS WHERE USERNAME = :uname OR EMAIL = :umail";
$sql = $this->conn->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL));
$sql->bindparam(':uname', $uname);
$sql->bindparam(':umail', $umail);
$sql->Execute();
$row = $sql->fetch(PDO::FETCH_ASSOC);
if($row == 1)
{
if(password_verify($upass, $userRow['PASSWORD']))
{
$_SESSION['USER_SESSION'] = $userRow['USERID'];
return true;
}
else
{
return false;
}
}
}
catch(PDOException $e)
{
echo $e->getMessage();
}
}
public function is_loggedin()
{
if(isset($_SESSION['USER_SESSION']))
{
return true;
}
}
public function redirect($url)
{
header("Location: $url");
}
public function doLogout()
{
session_destroy();
unset($_SESSION['USER_SESSION']);
return true;
}
}
?>
edit to the code i have added the whole user class but it is still returning false the password in the db looks like this $2y$10$16aMCo14n.QyON8dFsaFL..6Fi92LuBdWMCI3eAv3WHKJTblJKQ6q the column in the db is set to nvarchar (255) not null
got this:
public function Register($uname,$pass,$mail)
{
try
{
$new_password = password_hash($pass, PASSWORD_DEFAULT);
$stmt = $this->db->prepare("INSERT INTO users(username,email,password)
VALUES(:uname, :mail, :pass)");
$stmt->bindparam(":uname, $uname");
$stmt->bindparam(":mail, $mail");
$stmt->bindparam(":pass, $new_password");
$stmt->execute();
}
catch (PDOException $e)
{
echo $e->getMessage();
}
}
when I am trying to register it throws me an error:SQLSTATE[HY093]: Invalid parameter number: no parameters were bound. Was looking through the internet for the answers, but didn't find it yet, maybe you, guys , got some ideas?
You should use bindparam(':name', $name) instead of bindparam(':name, $name'). The first argument is a name of parameter slug, and the second argument is a variable you want to bind.
public function Register($uname,$pass,$mail)
{
try
{
$new_password = password_hash($pass, PASSWORD_DEFAULT);
$stmt = $this->db->prepare("INSERT INTO users(username,email,password)
VALUES(:uname, :mail, :pass)");
//note the quotes!
$stmt->bindParam(":uname", $uname);
$stmt->bindParam(":mail", $mail);
$stmt->bindParam(":pass", $new_password);
$stmt->execute();
}
catch (PDOException $e)
{
echo $e->getMessage();
}
}
I'm trying to create a login system using Slim Jquery and Ajax. I've got the log in part working with minimal issues, now I just need to be able to hash the password. I know I can use md5, sha1 and/or salt to hash but I know that it is recommenced that password_hash is used instead. I know how to hash with any of the other 3 I mentioned because while using bindParam you can just place it around the variable. My question is, how do I use password_hash with bindParam. The closest answer I found on this site didn't do much to help.
My current code is:
$app->post('/addUser/', 'addUser');
function addUser()
{
$request = \Slim\Slim::getInstance()->request();
$q = json_decode($request->getBody());
$sql = "INSERT INTO users(firstName, lastName, userName, password) VALUES (:firstName, :lastName, :userName, :password)";
try{
$dbConnection();
$stmt=$db->prepare($sql);
$stmt->bindParam("firstName", $q->firstName);
$stmt->bindParam("lastName", $q->lastName);
$stmt->bindParam("userName", $q->userName);
$stmt->bindParam("password", $q->password);
$stmt->execute();
$db=null;
}
catch(PDOException $e){
echo $e->getMessage();
}
}
Verify Code:
$app->post('/logIn/', 'lonIn');
function logIn()
{
$request = \Slim\Slim::getInstance()->request();
$q = json_decode($request->getBody());
$sql = "SELECT * FROM users WHERE userName=:userName";
try{
$db = getConnection();
$stmt=$db->prepare($sql);
$stmt->bindParam("userName", $q->userName);
$execute = $stmt->execute();
$db = null;
}
catch(PDOException $e)
{
echo $e->getMessage();
}
if($execute == true)
{
$array = $stmt->fetch(PDO::FETCH_ASSOC);
$hashedPassword = $array['password'];
if(password_verify($q->password), $hashedPassword))
{
echo 'Valid';
}
else
{
echo 'Invalid';
}
}
}
Any help would be appreciated.
To encrypt password you need to create a new variable $hashedPassword which you will store in the db for each user. When verifying the user you will select a user from the db passing their username and using password_verify($passToBeVerified,$ourHashedpasswordfromDb) this will return a boolean.
$app->post('/addUser/', 'addUser');
function addUser() {
$request = \Slim\Slim::getInstance()->request();
$q = json_decode($request->getBody());
$hashedPassword = password_hash($q->password, PASSWORD_BCRYPT);
$sql = "INSERT INTO users(firstName, lastName, userName, password) VALUES (:firstName, :lastName, :userName, :password)";
try {
$dbConnection();
$stmt = $db->prepare($sql);
$stmt->bindParam(":firstName", $q->firstName);
$stmt->bindParam(":lastName", $q->lastName);
$stmt->bindParam(":userName", $q->userName);
$stmt->bindParam(":password", $hashedPassword);
$execute = $stmt->execute();
if ($execute == true) {
$verifyUser = verifyUser($q->password, $q->userName);
if ($verifyUser == TRUE) {
echo 'valid Username and Password';
} else {
echo 'Invalid Username and password';
}
}
$db = null;
} catch (PDOException $e) {
echo $e->getMessage();
}
}
function verifyUser($passWordToVerify, $userNameToVerify) {
// $request = \Slim\Slim::getInstance()->request();
// $q = json_decode($request->getBody());
//Select a user data according to their username
$sql = "select firstName, lastName, userName, password from users where userName = :userName";
try {
$dbConnection();
$stmt = $db->prepare($sql);
$stmt->bindParam(":userName", $userNameToVerify);
$execute = $stmt->execute();
$db = null;
} catch (PDOException $e) {
echo $e->getMessage();
}
if ($execute == True) {
/*
* if the query executes and returs the user saved user details lets now compare
* the password from the db and the password that the user has entered
*/
$array = $stmt->fetch(PDO::FETCH_ASSOC);
$hashedPassword = $array['password'];
if (password_verify($passWordToVerify, $hashedPassword)) {
echo 'Password is valid!';
return true;
} else {
echo 'Invalid password.';
return false;
}
}
}
I create this class but i'm newbie in PHP OOP & PDO and i don't know how and where i must to make check to username is valid , email is valid and e.t.c..
This is my code
Class Users {
private $db;
public function __construct(Database $datebase) {
if (!$database instanceOf Database) {
throw new Exeption();
}
$this->db = $datebase;
}
public function userRegistration($username, $password, $email) {
$username = $_POST['username'];
$password = $_POST['password'];
$email = $_POST['email'];
$regdate = date('d.m.Y');
$query = $this->db->prepare("INSERT INTO `users` (`username`, `password`, `email`, `regdate`) VALUES (?, ?, ?, ?) ");
$query->bindValue(1, $username);
$query->bindValue(2, $password);
$query->bindValue(3, $email);
$query->bindValue(4, $regdate);
return ($query->execute()) ? true : false ;
}
}
If you want to check something, use Respect/Validation. For example:
$usernameValidator = v::alnum()->noWhitespace()->length(1,15);
$usernameValidator->validate($_POST['username']); //true or false
$passwordValidator = v::alnum()->length(10, null);
$passwordValidator->validate($_POST['password']); //true or false
v::email()->validate($_POST['email']); //true or false
To check if the username or email exist in your database you can use SQL to search the email or username.
$query = $this->db->prepare("SELECT * FROM users WHERE email = ? ");
$query->bindValue(1, $email);
If the query returns a value than the email or username already exist in your database. From there you can show your own validation.
To check check if user or email exist you don't need another class, just add another method called userExist or emailExist and run a query and then check if you get a result.
public function emailExist($email){
$query = $this->db->prepare("SELECT * FROM users WHERE email = ? ");
$query->bindValue(1, $email);
try{
$query->execute();
//use the if statement and $query->rowCount() to check if there is a result
$rows = $query->rowCount();
if($rows === 1){
return true;
} else {
return false;
}
}catch (PDOException $e) {
die($e->getMessage());
}
}
I am having a problem while including a php class with ajax.
Basically I have index.php which loads with ajax example.php. example.php includes init.php, which in turn includes a bunch of classes. I narrowed it down to users.php class, which I pasted below. I also put init.php under it just in case.
The file simply will not load with ajax. It works fine if i go directly to it.
<?php
class Users{
private $db;
public function __construct($database) {
$this->db = $database;
}
public function update_user($first_name, $last_name, $gender, $bio, $image_location, $id){
$query = $this->db->prepare("UPDATE `users` SET
`first_name` = ?,
`last_name` = ?,
`gender` = ?,
`bio` = ?,
`image_location`= ?
WHERE `id` = ?
");
$query->bindValue(1, $first_name);
$query->bindValue(2, $last_name);
$query->bindValue(3, $gender);
$query->bindValue(4, $bio);
$query->bindValue(5, $image_location);
$query->bindValue(6, $id);
try{
$query->execute();
}catch(PDOException $e){
die($e->getMessage());
}
}
public function change_password($user_id, $password) {
global $bcrypt;
/* Two create a Hash you do */
$password_hash = $bcrypt->genHash($password);
$query = $this->db->prepare("UPDATE `users` SET `password` = ? WHERE `id` = ?");
$query->bindValue(1, $password_hash);
$query->bindValue(2, $user_id);
try{
$query->execute();
return true;
} catch(PDOException $e){
die($e->getMessage());
}
}
public function recover($email, $generated_string) {
if($generated_string == 0){
return false;
}else{
$query = $this->db->prepare("SELECT COUNT(`id`) FROM `users` WHERE `email` = ? AND `generated_string` = ?");
$query->bindValue(1, $email);
$query->bindValue(2, $generated_string);
try{
$query->execute();
$rows = $query->fetchColumn();
if($rows == 1){
global $bcrypt;
$username = $this->fetch_info('username', 'email', $email); // getting username for the use in the email.
$user_id = $this->fetch_info('id', 'email', $email);// We want to keep things standard and use the user's id for most of the operations. Therefore, we use id instead of email.
$charset = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$generated_password = substr(str_shuffle($charset),0, 10);
$this->change_password($user_id, $generated_password);
$query = $this->db->prepare("UPDATE `users` SET `generated_string` = 0 WHERE `id` = ?");
$query->bindValue(1, $user_id);
$query->execute();
mail($email, 'Your password', "Hello " . $username . ",\n\nYour your new password is: " . $generated_password . "\n\nPlease change your password once you have logged in using this password.\n\n-Example team");
}else{
return false;
}
} catch(PDOException $e){
die($e->getMessage());
}
}
}
public function fetch_info($what, $field, $value){
$allowed = array('id', 'country', 'money', 'flag', 'email'); // I have only added few, but you can add more. However do not add 'password' eventhough the parameters will only be given by you and not the user, in our system.
if (!in_array($what, $allowed, true) || !in_array($field, $allowed, true)) {
throw new InvalidArgumentException;
}else{
$query = $this->db->prepare("SELECT $what FROM `users` WHERE $field = ?");
$query->bindValue(1, $value);
try{
$query->execute();
} catch(PDOException $e){
die($e->getMessage());
}
return $query->fetchColumn();
}
}
public function confirm_recover($email){
$username = $this->fetch_info('username', 'email', $email);// We want the 'id' WHERE 'email' = user's email ($email)
$unique = uniqid('',true);
$random = substr(str_shuffle('ABCDEFGHIJKLMNOPQRSTUVWXYZ'),0, 10);
$generated_string = $unique . $random; // a random and unique string
$query = $this->db->prepare("UPDATE `users` SET `generated_string` = ? WHERE `email` = ?");
$query->bindValue(1, $generated_string);
$query->bindValue(2, $email);
try{
$query->execute();
mail($email, 'Recover Password', "Hello " . $username. ",\r\nPlease click the link below:\r\n\r\nhttp://www.example.com/recover.php?email=" . $email . "&generated_string=" . $generated_string . "\r\n\r\n We will generate a new password for you and send it back to your email.\r\n\r\n-- Example team");
} catch(PDOException $e){
die($e->getMessage());
}
}
public function user_exists($username) {
$query = $this->db->prepare("SELECT COUNT(`id`) FROM `users` WHERE `username`= ?");
$query->bindValue(1, $username);
try{
$query->execute();
$rows = $query->fetchColumn();
if($rows == 1){
return true;
}else{
return false;
}
} catch (PDOException $e){
die($e->getMessage());
}
}
public function email_exists($email) {
$query = $this->db->prepare("SELECT COUNT(`id`) FROM `users` WHERE `email`= ?");
$query->bindValue(1, $email);
try{
$query->execute();
$rows = $query->fetchColumn();
if($rows == 1){
return true;
}else{
return false;
}
} catch (PDOException $e){
die($e->getMessage());
}
}
public function register($username, $password, $email, $country, $timezone, $dst){
global $bcrypt; // making the $bcrypt variable global so we can use here
$date = date( 'Y-m-d' );
$ip = $_SERVER['REMOTE_ADDR']; // getting the users IP address
$email_code = $email_code = uniqid('code_',true); // Creating a unique string.
$password = $bcrypt->genHash($password);
$query = $this->db->prepare("INSERT INTO `users` (`username`, `password`, `email`, `country`, `timezone`, `dst`, `ip`, `regdate`, `email_code`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) ");
$query->bindValue(1, $username);
$query->bindValue(2, $password);
$query->bindValue(3, $email);
$query->bindValue(4, $country);
$query->bindValue(5, $timezone);
$query->bindValue(6, $dst);
$query->bindValue(7, $ip);
$query->bindValue(8, $date);
$query->bindValue(9, $email_code);
try{
$query->execute();
mail($email, 'Please activate your account', "Hello " . $username. ",\r\nThank you for registering with us. Please visit the link below so we can activate your account:\r\n\r\nhttp://www.touringlegends.com/register.php?email=" . $email . "&email_code=" . $email_code . "\r\n\r\n-- Example team");
}catch(PDOException $e){
die($e->getMessage());
}
}
public function activate($email, $email_code) {
$query = $this->db->prepare("SELECT COUNT(`id`) FROM `users` WHERE `email` = ? AND `email_code` = ? AND `accountlevel` = ?");
$query->bindValue(1, $email);
$query->bindValue(2, $email_code);
$query->bindValue(3, 0);
try{
$query->execute();
$rows = $query->fetchColumn();
if($rows == 1){
$query_2 = $this->db->prepare("UPDATE `users` SET `accountlevel` = ? WHERE `email` = ?");
$query_2->bindValue(1, 1);
$query_2->bindValue(2, $email);
$query_2->execute();
return true;
}else{
return false;
}
} catch(PDOException $e){
die($e->getMessage());
}
}
public function email_confirmed($email) {
$query = $this->db->prepare("SELECT COUNT(`id`) FROM `users` WHERE `email`= ? AND `accountlevel` >= ?");
$query->bindValue(1, $email);
$query->bindValue(2, 1);
try{
$query->execute();
$rows = $query->fetchColumn();
if($rows == 1){
return true;
}else{
return false;
}
} catch(PDOException $e){
die($e->getMessage());
}
}
public function login($email, $password) {
global $bcrypt; // Again make get the bcrypt variable, which is defined in init.php, which is included in login.php where this function is called
$query = $this->db->prepare("SELECT `password`, `id` FROM `users` WHERE `email` = ?");
$query->bindValue(1, $email);
try{
$query->execute();
$data = $query->fetch();
$stored_password = $data['password']; // stored hashed password
$id = $data['id']; // id of the user to be returned if the password is verified, below.
if($bcrypt->verify($password, $stored_password) === true){ // using the verify method to compare the password with the stored hashed password.
return $id; // returning the user's id.
}else{
return false;
}
}catch(PDOException $e){
die($e->getMessage());
}
}
public function userdata($id) {
$query = $this->db->prepare("SELECT * FROM `users` WHERE `id`= ?");
$query->bindValue(1, $id);
try{
$query->execute();
return $query->fetch();
} catch(PDOException $e){
die($e->getMessage());
}
}
public function get_users() {
$query = $this->db->prepare("SELECT * FROM `users` ORDER BY `time` DESC");
try{
$query->execute();
}catch(PDOException $e){
die($e->getMessage());
}
return $query->fetchAll();
}
}
init.php:
<?php
session_start();
require($_SERVER['DOCUMENT_ROOT'].'/core/connect/database.php');
require($_SERVER['DOCUMENT_ROOT'].'/core/classes/users.php');
require($_SERVER['DOCUMENT_ROOT'].'/core/classes/general.php');
require($_SERVER['DOCUMENT_ROOT'].'/core/classes/bcrypt.php');
require($_SERVER['DOCUMENT_ROOT'].'/core/classes/garage.php');
// error_reporting(0);
$users = new Users($db);
$general = new General();
$bcrypt = new Bcrypt(12);
$errors = array();
if ($general->logged_in() === true) {
$user_id = $_SESSION['id'];
$user = $users->userdata($user_id);
}
ob_start();
Here is the js loading the files (its a bit weird because its reloading jscrollpane, but working fine with html and php that dosent need external classes):
// Ajax
$(function () {
var api = $("#garagecontent").jScrollPane().data('jsp');
var reinitialiseScrollPane = function()
{
api.reinitialise();
}
// attaching click handler to links
$(document).on('click', '#garagecontainer a[href]', function (e) {
// cancel the default behaviour
e.preventDefault();
// get the address of the link
var href = $(this).attr('href');
// getting the desired element for working with it later
var $wrap = $('#garagecontent');
$wrap
// removing old data
api.getContentPane()
// load the remote page
.load(href, reinitialiseScrollPane , function (){
}
);
});
});
I have narrowed it down to users.php because it will work when I remove it from the includes (and its functions in init.php).
Can anyone spot what is breaking my code?
The solution to this question was using an autoloader. The page was breaking because of duplicate classes being called. My fault for having errors disabled i guess.