I'm having some issues with my user registration system--namely the CheckUsername function inside of it.
This code:
function checkUsername($username) {
if ( preg_match('/\s/',$username)) {
return false;
}
if(!preg_match('/^[\w\-]+$/', $username)) {
return false;
}
if(strlen($username) == 0) {
return false;
}
else {
$sql = "SELECT count(username) FROM users WHERE username = :username LIMIT 1";
$que = $this->db->prepare($sql);
$que->bindParam('username', $username);
try {
$que->execute();
while($row = $que->fetch(PDO::FETCH_BOTH)) {
if($row[0] > 0) {
return false;
}
else {
return true;
}
}
}
catch(PDOException $e) {}
}
}
Isn't working as designed. Users are able to register with names like <script>, which I clearly do not want.
function registerUser($password, $username)
{
if(!$this->checkUsername($username))
{
header('location:index.php');
}
else
{
$password = $this->passwordEncryption($password);
$sql = "INSERT INTO users(username, password) VALUES (:username, :password);";
$sql .= "INSERT INTO bank_accounts(balance, fuel_cell, energy_cell) VALUES (100,100, 100);";
$que = $this->db->prepare($sql);
$que->bindParam('username', $username);
$que->bindParam('password', $password);
try{
$que->execute();
$que->nextRowset();
$this->login($username, $password);
}
catch(PDOException $e){}
}
}
This states if there is not a word character or - so any string that contains a word character or - and anything else is OK:
if(!preg_match('/^[\w\-]+$/', $username)) {
return false;
}
You probably want if there is any character that is not a word character or -
if(preg_match('/[^\w\-]+$/', $username)) {
return false;
}
try the following :)
function checkUsername($username) {
$username = trim("$username");
if ( empty($username) || !preg_match("/^a-z0-9\-]+$/i", $username)) {
return false;
}
$sql = "SELECT count(1) FROM users WHERE username = :username LIMIT 1";
$que = $this->db->prepare($sql);
$que->bindParam('username', $username);
try{
$que->execute();
while($row = $que->fetch(PDO::FETCH_BOTH)) {
if($row[0] > 0) {
return false;
} else {
return true;
}
}
} catch(PDOException $e){}
}
Related
I am doing an android project and I've got a problem while logging into the account. I am able to login even if the password is incorrect or empty. I am unable to recognize the error. I have checked my code but nothing helped me Could anyone help me with this?
My Code:
userLogin.php
require_once '../includes/DbOperations.php';
$response = array();
if($_SERVER['REQUEST_METHOD']=='POST'){
if(isset($_POST['username']) and isset($_POST['password'])){
$db = new DbOperations();
$result = $db->userLogin($_POST['username'], $_POST['password']);
if ($result == 1) {
# code...
$user = $db->getUserByUsername($_POST['username']);
$response['error'] = false;
$response['id'] = $user['id'];
$response['email'] = $user['email'];
$response['username'] = $user['username'];
$response['phone'] = $user['phone'];
$response['gender'] = $user['gender'];
$response['message'] = "Found successfully";
}
elseif ($result == 2) {
# code...
$response['error'] = true;
$response['message'] = "Some error occurred please try again";
}
}else{
$response['error'] = true;
$response['message'] = "Required fields are missing";
}
}
echo json_encode($response);
DbOperations.php
public function userLogin($username, $pass){
$password = md5($pass);
$stmt = $this->con->prepare("SELECT * FROM users WHERE username = ? AND password = ?;");
if($stmt != FALSE){
$stmt->bind_param("ss",$username,$password);
if($stmt->execute()){
return 1;
}else{
return 2;
}
$stmt->store_result();
$stmt->close();
else
{
var_dump($this->con->error);
}
}
public function getUserByUsername($username){
$stmt = $this->con->prepare("SELECT * FROM users WHERE username = ?;");
if($stmt != FALSE){
$stmt->bind_param("s",$username);
$stmt->execute();
return $stmt->get_result()->fetch_assoc();
}
else
{
var_dump($this->con->error);
}
}
please return the value if records found but you are returning the value if query executed successfully.
Your code :
if($stmt->execute()){
return 1;
}else{
return 2;
}
Should be :
if($stmt->num_rows > 0){
return 1;
}else{
return 2;
}
And as per your code if you enter wrong username than it should work to.
if($stmt->execute() != FALSE) is not correct. see below code:
public function userLogin($username, $pass){
$password = md5($pass);
$stmt = $this->con->prepare("SELECT * FROM users WHERE username = ? AND password = ?;");
if($stmt != FALSE){
$stmt->bind_param("ss",$username,$password);
$stmt->execute()
$stmt->store_result();
$rows = $stmt->num_rows;
$stmt->close();
return $rows;
else
{
var_dump($this->con->error);
}
}
public function getUserByUsername($username){
$stmt = $this->con->prepare("SELECT * FROM users WHERE username = ?;");
if($stmt != FALSE){
$stmt->bind_param("s",$username);
$stmt->execute();
return $stmt->get_result()->fetch_assoc();
}
else
{
var_dump($this->con->error);
}
}
its my first time here i have a question im making a register form but i need to insert to 2 databases here is my code.
when i run its only register in one database sometimes db1 other times db2
-Sorry for my bad english
-Here's register.php
require_once 'config/dbconfig.php';
if($user->is_loggedin()!="")
{
$user->redirect('home.php');
}
if(isset($_POST['btn-signup']))
{
$uname = trim($_POST['txt_uname']);
$umail = trim($_POST['txt_umail']);
$upass = trim($_POST['txt_upass']);
$rpass = trim($_POST['txt_rpass']);
if($uname=="") {
$error[] = "provide username !";
}
else if($umail=="") {
$error[] = "provide email id !";
}
else if(!filter_var($umail, FILTER_VALIDATE_EMAIL)) {
$error[] = 'Please enter a valid email address !';
}
else if($upass=="") {
$error[] = "provide password !";
}
else if(strlen($upass) < 6){
$error[] = "Password must be atleast 6 characters";
}
elseif($upass != $rpass){
$msg = "passwords doesn't match";
}
else
{
try
{
$stmt = $DB_con->prepare("SELECT user_name,user_email FROM users WHERE user_name=:uname OR user_email=:umail");
$stmt2 = $DB_con2->prepare("SELECT user_name,user_email FROM users WHERE user_name=:uname OR user_email=:umail");
$stmt->execute(array(':uname'=>$uname, ':umail'=>$umail));
$stmt2->execute(array(':uname'=>$uname, ':umail'=>$umail));
$row=$stmt->fetch(PDO::FETCH_ASSOC);
if($row['user_name']==$uname) {
$error[] = "sorry username already taken !";
}
else if($row['user_email']==$umail) {
$error[] = "sorry email id already taken !";
}
else
{
if($user->register($fname,$lname,$uname,$umail,$upass))
{
$user->redirect('register.php?joined');
}
}
}
catch(PDOException $e)
{
echo $e->getMessage();
}
}
}
-Here Class.User.php
<?php
class USER
{
private $db;
function __construct($DB_con)
{
$this->db = $DB_con;
}
public function register($fname,$lname,$uname,$umail,$upass)
{
try
{
$new_password = password_hash($upass, PASSWORD_DEFAULT);
$stmt = $this->db->prepare("INSERT INTO users(user_name,user_email,user_pass)
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 login($uname,$umail,$upass)
{
try
{
$stmt = $this->db->prepare("SELECT * FROM users WHERE user_name=:uname OR user_email=:umail LIMIT 1");
$stmt->execute(array(':uname'=>$uname, ':umail'=>$umail));
$userRow=$stmt->fetch(PDO::FETCH_ASSOC);
if($stmt->rowCount() > 0)
{
if(password_verify($upass, $userRow['user_pass']))
{
$_SESSION['user_session'] = $userRow['user_id'];
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 logout()
{
session_destroy();
unset($_SESSION['user_session']);
return true;
}
}
?>
-and the DBConfig.php
<?php
session_start();
$DB_host = "localhost";
$DB_user = "root";
$DB_pass = "";
try
{
$DB_con = new PDO("mysql:host= {$DB_host};dbname=dblogin",$DB_user,$DB_pass);
$DB_con2 = new PDO("mysql:host= {$DB_host};dbname=dblogin2",$DB_user,$DB_pass);
$DB_con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$DB_con2->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $e)
{
echo $e->getMessage();
}
include_once 'class.user.php';
$user = new USER($DB_con);
$user2 = new USER($DB_con2);
I am trying to make my own custom CMS, I can register users and can login aswel, Now I am trying to make a function for user roles,
File: class.user.php
function getUserrole() {
$username = htmlentities($_SESSION['user_session']);
$stmt = $this->db->prepare('SELECT * FROM users WHERE user_name = :username');
$stmt->bindParam(':user_name', $username);
$stmt->execute();
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$userrole = $row['user_role'];
if($userrole == 3) {
return $userrole = 3;
}
if($userrole == 2) {
return $userrole = 2;
}
if($userrole == 1) {
return $userrole = 1;
}
if($userrole == 0) {
return $userrole = 0;
}
}
File: Home.php
<?php
$userrole = getUserrole();
if($userrole == 1) {
echo "Hi Admin";
}
else {
echo "You are not a admin";
}
?>
When I try to do this, the error shows up:
Fatal error: Call to undefined function getUserrole() in /Applications/MAMP/htdocs/test/home.php on line 24
I can see something wrong and I was hoping you guys could help me out here:)
Entire class.user.php :
<?php
class USER
{
private $db;
function __construct($DB_con)
{
$this->db = $DB_con;
}
public function register($uname,$umail,$upass)
{
try
{
$new_password = password_hash($upass, PASSWORD_DEFAULT);
$stmt = $this->db->prepare("INSERT INTO users(user_name,user_email,user_pass)
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 login($uname,$umail,$upass)
{
try
{
$stmt = $this->db->prepare("SELECT * FROM users WHERE user_name=:uname OR user_email=:umail LIMIT 1");
$stmt->execute(array(':uname'=>$uname, ':umail'=>$umail));
$userRow=$stmt->fetch(PDO::FETCH_ASSOC);
if($stmt->rowCount() > 0)
{
if(password_verify($upass, $userRow['user_pass']))
{
$_SESSION['user_session'] = $userRow['user_id'];
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 logout()
{
session_destroy();
unset($_SESSION['user_session']);
return true;
}
function getUserrole() {
$username = htmlentities($_SESSION['user_session']);
$stmt = $this->db->prepare('SELECT * FROM users WHERE user_name = :username');
$stmt->bindParam(':user_name', $username);
$stmt->execute();
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$userrole = $row['user_role'];
if($userrole == 3) {
return $userrole = 3;
}
if($userrole == 2) {
return $userrole = 2;
}
if($userrole == 1) {
return $userrole = 1;
}
if($userrole == 0) {
return $userrole = 0;
}
}
}
?>
Require the class within your home.php, init it and than call the function
<?php
require_once 'class.user.php';
$userClass = new USER(<yourdbcon>);
$userrole = $userClass->getUserrole();
if($userrole == 1) {
echo "Hi Admin";
}
else {
echo "You are not a admin";
}
?>
I have the following php functions that process a user logging in. The functions are part of a class User.
/*
* detail() function to get a detail from a database
* exists() function to check if something exists in a database
*/
private function generate($password, $username = null) {
if(is_null($username)) {
$date = '0000-00-00';
} else {
$date = $this->_db->detail('last_active', 'users', 'username', $username);
}
// This is not the real thing but it will do as an example
$salt = md5(strrev($password.$date));
$password = md5($salt.$password.$date).strrev($password);
return $password;
}
public function login($data = array()) {
// Check if the user exists
$username = $data['username'];
if($this->_db->exists('username', 'users', 'username', $username)) {
$password = $this->generate($data['password'], $username);
// If the account is active
if ($this->_db->detail('active', 'users', 'username', $username) === 1) {
$stmt = $this->_db->mysqli->prepare("SELECT `username`, `password` FROM `users` WHERE `username` = ? AND `password` = ? AND `active` = 1");
$stmt->bind_param('ss', $username, $password);
$stmt->execute();
$stmt->store_result();
if($stmt->num_rows >= 1) {
// Function to update last_active
if($this->updateLastActive($username)) {
// Function to update password
if($this->updatePassword($username, $this->generate($password, $username))) {
// Set the session
$this->_session->set('user', $this->_db->detail('id', 'users', 'username', $username));
if($this->_session->exists('user')) {
return true;
} else {
echo 'Logging in went wrong';
return false;
}
} else {
echo 'Editing the password went wrong';
return false;
}
} else {
echo 'Editing last active date went wrong';
return false;
}
} else {
echo 'Wrong username and password combination';
return false;
}
} else {
echo 'Account not active';
return false;
}
} else {
echo 'Username doesn\'t exists';
return false;
}
}
private function updateLastActive($username) {
$date = date('Y-m-d');
$stmt = $this->_db->mysqli->prepare("UPDATE `users` SET `last_active` = ? WHERE `username` = ?");
$stmt->bind_param('ss', $date, $username);
$stmt->execute();
if($stmt->affected_rows >= 1) {
return true;
} else {
return false;
}
}
private function updatePassword($username, $password) {
$stmt = $this->_db->mysqli->prepare("UPDATE `users` SET `password` = ? WHERE `username` = ?");
$stmt->bind_param('ss', $password, $username);
$stmt->execute();
if($stmt->affected_rows >= 1) {
return true;
} else {
return false;
}
}
The user can login with no problem when he just registered. But when the user is logged out and than tries to login again it will fail. The part I get an error on is the following:
$stmt = $this->_db->mysqli->prepare("SELECT `username`, `password` FROM `users` WHERE `username` = ? AND `password` = ? AND `active` = 1");
I tried to find out where the script fails with echo on different places in the functions but I couldn't find the error. The reason why the generate() function has $username = null is because the same function is used for registration.
So all functions are working but they only work once so this leaves me that someting in the generate() function is wrong. I always get the message that there is something wrong with the username / password combination
If someone could point me in the right direction I would be very happy.
Thanks in advance
UPDATE
The detail() and exists() functions are part of a class Database.
public function detail($detail, $table, $column, $value) {
if(is_array($detail)) {
$data = array();
foreach($detail as $key) {
$stmt = $this->mysqli->prepare("SELECT `$key` FROM `$table` WHERE `$column` = ?");
if(is_numeric($value)) {
$stmt->bind_param('i', $value);
} else {
$stmt->bind_param('s', $value);
}
$stmt->execute();
$stmt->bind_result($detail);
$stmt->fetch();
$data[] = $detail;
$stmt = null;
}
return $data;
} else {
$stmt = $this->mysqli->prepare("SELECT `$detail` FROM `$table` WHERE `$column` = ?");
if(is_numeric($value)) {
$stmt->bind_param('i', $value);
} else {
$stmt->bind_param('s', $value);
}
$stmt->execute();
$stmt->bind_result($detail);
$stmt->fetch();
return $detail;
}
}
public function exists($detail, $table, $column, $value) {
$stmt = $this->mysqli->prepare("SELECT `$detail` FROM `$table` WHERE `$column` = ?");
switch(is_numeric($value)) {
case true:
$stmt->bind_param('i', $value);
break;
case false:
$stmt->bind_param('s', $value);
break;
}
$stmt->execute();
$stmt->store_result();
if($stmt->num_rows >= 1) {
return true;
} else {
return false;
}
}
Create a hash field in your table, make it long enough to avoid length issue.
md5() is not acceptable now, you should be using better hash function such as password_hash()
Register:
private function register($username, $password) {
//safer than md5() anyway
$hash = password_hash($password, PASSWORD_DEFAULT);
$sql = 'INSERT INTO table_name (`username`, `hash`) VALUES (?, ?);'
$stmt = $this->_db->mysqli->prepare($sql);
$stmt->bind_param('ss', $username, $hash);
$stmt->execute();
if($stmt->affected_rows >= 1) {
return true;
} else {
return false;
}
}
Login :
public function login($username, $password) {
// Check if the user exists
if($this->_db->exists('username', 'users', 'username', $username)) {
// If the account is active
if ($this->_db->detail('active', 'users', 'username', $username) === 1) {
$sql = 'SELECT `username`, `hash` FROM `users` WHERE `username` = ? AND `active` = 1';
$stmt = $this->_db->mysqli->prepare();
$stmt->bind_param('ss', $username, $hash);
$stmt->execute();
$stmt->store_result();
if($stmt->num_rows === 1) {
if (password_verify($password, $hash)) {
// Function to update last_active
if($this->updateLastActive($username)) {
echo 'last active updated, Login successful';
return true;
} else {
echo 'Editing last active date went wrong';
return false;
}
} else {
echo 'Wrong username and password combination';
return false;
}
} else {
echo 'Account not active';
return false;
}
} else {
echo 'Username doesn\'t exists';
return false;
}
}
}
Of course you can still use custom salt, for example
$hash = password_hash($password
,PASSWORD_DEFAULT
,array('salt' =>generate()));//generate() returns the salt
I have the following function that checks for a user login. At it's current state it checks either the username or email and the password ( hash ) and if the result match the ones in the db it returns some values ( please make abstraction of the other variables or functions that have no sense in there if you cannot see them ):
// Start Checking The Login Credentials
public function checkUserLogin($username, $password) {
$password = hash_hmac('sha512', $password, $this->salt($password));
if(preg_match("/^[_a-z0-9-]+(\.[_a-z0-9-]+)*#[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$/i", $username)){
$identifier = 'user_email';
} else {
$identifier = 'user_username';
}
$sql = 'SELECT user_username,user_level FROM users WHERE '.$identifier.' = ? AND user_password = ?';
// Check Login Attempts
if (isset($_SESSION['attempts']) && $_SESSION['attempts'] >= NUMBER_OF_ATTEMPTS) {
$lockdown = true;
$message['lockdown'] = true;
$message['message'] = SYSTEM_LOCKDOWN_MESSAGE;
return json_encode($message);
} else {
if ($stmt = $this->connect->prepare($sql)) {
$stmt->bind_param('ss', $username, $password);
$stmt->execute();
$stmt->bind_result($username, $level);
if ($stmt->fetch()) {
$stmt->close();
$_SESSION['member_logged_in'] = true;
$_SESSION['username'] = $username;
$_SESSION['level'] = $level;
$_SESSION['attempts'] = 0;
$ip = $this->getIP();
$sql = "UPDATE users SET user_last_login_date = NOW(), user_last_login_ip = '$ip' WHERE user_username = '$username'";
if ($stmt = $this->connect->prepare($sql)) {
$stmt->execute();
$stmt->close();
} else {
$error = true;
$message['error'] = true;
$message['message'] = CANNOT_PREPARE_DATABASE_CONNECTION_MESSAGE;
return json_encode($message);
}
$message['level'] = $level;
if( $level = 0 ) {
$_SESSION['standard'] = true;
} elseif( $level = 1 ) {
$_SESSION['special'] = true;
} elseif( $level = 2 ) {
$_SESSION['admin'] = true;
}
$error = false;
$message['error'] = false;
$message['message'] = SUCCESFUL_LOGIN_MESSAGE;
return json_encode($message);
} else {
#$_SESSION['attempts'] = $_SESSION['attempts'] + 1;
$error = true;
$message['error'] = true;
$message['message'] = FAILED_LOGIN_MESSAGE;
return json_encode($message);
}
}
}
}
Now, what I'm trying to do is before returning the values if the credentials are found in the db and match, check for another value in the db called user_disabled which can be either 0 or 1 and if the 1 value is found return another message, something like This account has been disabled and if 0 is found, continue with the rest of the code as it was before ( a successful login ).
I have the following code which does approximately what I need, but when I tried to place inside this public function it doesn't work:
$sql = "SELECT user_disabled FROM users WHERE user_username = '$username'";
if ($stmt = $this->connect->prepare($sql)) {
$stmt->execute();
$stmt->bind_result($disabled);
$stmt->fetch();
$stmt->close();
if($disabled = 0){
/* Here is what should happen if the user is not blocked | The code after "$stmt->fetch()" */
} else {
#$_SESSION['attempts'] = $_SESSION['attempts'] + 1;
$error = true;
$message['error'] = true;
$message['message'] = 'ceva';
return json_encode($message);
}
} else {
$error = true;
$message['error'] = true;
$message['message'] = CANNOT_PREPARE_DATABASE_CONNECTION_MESSAGE;
return json_encode($message);
}
Could someone help me out with this because I cannot figure out how to do it right ?
The line
if($disabled = 0){
should read
if($disabled == 0){