I have this code that is used to process user inputs from a from with the parameters email and password.
$app->post('/login', function() use ($app) {
// check for required params
verifyRequiredParams(array('email', 'password'));
// reading post params
$email = $app->request()->post('email');
$password = $app->request()->post('password');
$response = array();
$db = new DbHandler();
// check for correct email and password
if ($db->checkLogin($email, $password)) {
// get the user by email
$user = $db->getUserByEmail($email);
if ($user != NULL) {
$response["response_status"] =array('status_code'=>0, 'status_message' => 'Login Successfuly');
$response["customer_creds"] =array(array('customer_names'=>$user['name'], 'customer_email' => $user['email'], 'customer_id' => $user['customer_id'], 'customer_type' => $user['customer_type'], 'rating' => $user['rating']));
$response["customer_payment_instruments"] =array(array('payment_method'=>$user['payment_method1'], 'account_number' => $user['account_number1']),array('payment_method'=>$user['payment_method2'], 'account_number' => $user['account_number2']),array('payment_method'=>$user['payment_method3'], 'account_number' => $user['account_number3']));
$response["customer_vehicle_details"] =array(array('vehicle_plate'=>$user['vehicle_plate1'], 'vehicle_make' => $user['vehicle_make1'], 'vehicle_model' => $user['vehicle_model1'], 'vehicle_colour' => $user['vehicle_colour1'], 'vehicle_id' => $user['vehicle_id1']), array('vehicle_plate'=>$user['vehicle_plate2'], 'vehicle_make' => $user['vehicle_make2'], 'vehicle_model' => $user['vehicle_model2'], 'vehicle_colour' => $user['vehicle_colour2'], 'vehicle_id' => $user['vehicle_id2']));
} else {
// unknown error occurred
$response["response_status"] =array('status_code'=>1, 'status_message' => 'An unknown error occurred. Please try again');
//$response['error'] = true;
//$response['message'] = "An error occurred. Please try again";
}
} else {
// user credentials are wrong
$response["response_status"] =array('status_code'=>1, 'status_message' => 'Login failed. Incorrect credentials');
}
echoRespnse(200, $response);
});
This script checks if the email and password exist in the database and give a json response.
public function checkLogin ($email, $password) {
// fetching user by email
$stmt = $this->conn->prepare("SELECT password_hash FROM users WHERE email = ?");
$stmt->bind_param("s", $email);
$stmt->execute();
$stmt->bind_result ($password_hash);
$stmt->store_result();
if ($stmt->num_rows > 0) {
// Found user with the email
// Now verify the password
$stmt->fetch();
$stmt->close();
if (PassHash::check_password($password_hash, $password)) {
// User password is correct
return TRUE;
} else {
// user password is incorrect
return FALSE;
}
} else {
$stmt->close();
// user not existed with the email
return FALSE;
}
}
/**
* Fetching user by email
* #param String $email User email id
*/
public function getUserByEmail($email) {
$stmt = $this->conn->prepare("SELECT name, email, customer_id, customer_type, rating, payment_method1, account_number1, payment_method2, account_number2, payment_method3, account_number3, vehicle_plate1, vehicle_make1, vehicle_model1, vehicle_colour1, vehicle_id1, vehicle_plate2, vehicle_make2, vehicle_model2, vehicle_colour2, vehicle_id2, api_key, status, created_at FROM users WHERE email = ?");
$stmt->bind_param("s", $email);
if ($stmt->execute()) {
$user = $stmt->get_result()->fetch_assoc();
$stmt->close();
return $user;
} else {
return NULL;
}
}
I am now trying to figure out a way of allowing folks to parse json data. Any workarouds in doing this? For now script only accepts data from a form. Is there a way of allowing raw data in the format
{
"email":"",
"password":""
}
Here is the code that you can use in your current code:
Replace this code:
// reading post params
$email = $app->request()->post('email');
$password = $app->request()->post('password');
With
// reading request body
$requestBody = $app->request->getBody();
// parsing json data to php
$requestData = json_decode($requestBody, 1);
// checking if email or password is set, if not the return response
if(empty($requestData['email']) || empty($requestData['password'])) {
echoRespnse(400, ['message' => 'username/password cannot be empty']);
}
$email = $requestData['email'];
$password = $requestData['password'];
Hope this should work!!
Related
Hi I would like to add here a case sensitive error trap on my login function, by the way i am using MVC FRAMEWORK anyone be of help ? I want to make the username and password case sensitive so that is the input doesn't match an error exception will occur............... I have tried but failed maybe someone can assist me on hot to go about this dilemma
//THIS IS THE CODE OF MY CONTROLLER
public function login() {
if(isLoggedIn()) {
header("Location: " .URLROOT . "/");
}
$data = [
'title' => 'Login page',
'username' => '',
'password' => '',
'usernameError' => '',
'passwordError' => ''
];
//Check for post
if($_SERVER['REQUEST_METHOD'] == 'POST'){
//Sanitize post data
$_POST = filter_input_array(INPUT_POST);
$data = [
'username' => trim($_POST['username']),
'password' => trim($_POST['password']),
'usernameError' => '',
'passwordError' => '',
];
$findUser = $this->userModel->findUser($data);
//Validate username
if(empty($data['username'])){
$data['usernameError'] = 'Please enter a username.';
}else if($findUser === false){
$data['usernameError'] = "Username not registered";
}
//Validate username
if(empty($data['password'])){
$data['passwordError'] = 'Please enter a password.';
}else if($findUser === false){
$data['passwordError'] = "Password not registered";
}
$findUser = $this->userModel->getUserDetails($data);
//Check if all errors are empty
if(empty($data['usernameError']) && empty($data['passwordError'])){
$loggedInUser = $this->userModel->login($data['username'], $data['password']);
if($loggedInUser){
$this->createUserSession($loggedInUser);
}else {
$data['passwordError'] = 'Password is incorrect. Please try again.';
$this->view('users/login',$data);
}
}
}else{
$data = [
'username' => '',
'password' => '',
'usernameError' => '',
'passwordError' => ''
];
}
//THIS IS THE CODE OF MY MODEL
public function login($username, $password) {
$this->db->query('SELECT * FROM user WHERE username = :username');
//Bind value
$this->db->bind(':username', $username);
$row = $this->db->single();
$hashedPassword = !empty($row) ? $row->password:'';
if(password_verify($password, $hashedPassword)){
return $row;
}else {
return false;
}
}
$this->view('users/login', $data);
}
Case sensitive error trap
If you need to make a case-sensitive query, it is very easy to do using the BINARY operator, which forces a byte by byte comparison:
SELECT * FROM `table` WHERE BINARY `column` = 'value'
The password is already case-sensitive, since it's using the native password_hash and password_verify functions, it can be easily tested with:
var_dump(password_verify('AAA', password_hash('AAA', PASSWORD_DEFAULT))); // true
var_dump(password_verify('AAA', password_hash('aaa', PASSWORD_DEFAULT))); // false
If you really want to have the username case-sensitive, you can also use a case-sensitive collation for the username field, such as utf8mb4_0900_as_cs, more info here.
ALTER TABLE `users` CHANGE COLUMN `username` `username` VARCHAR(255) CHARACTER SET 'utf8mb4' COLLATE 'utf8mb4_0900_as_cs' NOT NULL;
Test case:
INSERT INTO `users` (`username`) VALUES ('test');
SELECT * FROM `users` WHERE `username`='TEST'; /* returns nothing as expected */
i have 3 tables within my db: users, lots and auction
lots contains lotid, title, desc, photo, and fk a_id and this table is products and links to auction through a_id as that shows whos selling product
auction contains a_id,name, address and date. this table is basically the seller info
users contains all information related to logging in and out
currently on my website you can register login and logout without anyissues now im trying to add a search onto the page so you can search for items that are listed and it should return the output showing all fields from lotid and also show the auction data so the data returned is like this
the db has a few records for now but will be populated with around 500 lot records and 50 auction records so the search needs to be able to go through this and only return relevant information the search criteria should be for example: theres 100 types of phone if i search "phone" it should show iphones aswell as anything else that contains phone within the title so red phone would return aswell. but currently im really struggling and have massive errors im new to using mvc so it could be im using the wrong files like views models etc but my log in system works fine so i need help adding this search function as currently its like this when i tested it here is my directories i currently tried this search function by adding the search form to the auction.php page and using the users.php controller although i may need new controller for this page
code for auction.php
<?php
require APPROOT . '/views/includes/head.php';
?>
<div class="navbar">
<?php
require APPROOT . '/views/includes/navigation.php';
?>
</div>
<form action="search.php" method="GET">
<input type="text" name="search" placeholder="Search">
<button type="submit" name="submit-search"></button>
</form>
<h1> this is Auction Page </h1>
<h2>All products</h2>
<div class="product-container">
<?php
$this->db->query("SELECT * FROM article");
?>
</div>
user model code
<?php
class User{
private $db;
public function __construct(){
$this->db = new Database;
}
public function getUsers(){
$this->db->query("SELECT * FROM users");
$result = $this->db->resultSet();
return $result;
}
public function register($data){
$this->db->query('INSERT INTO users (username, email, password)
VALUES (:username, :email, :password)');
//bind values
$this->db->bind(':username', $data['username']);
$this->db->bind(':email', $data['email']);
$this->db->bind(':password', $data['password']);
//execute
if ($this->db->execute()){
return true;
}else{
return false;
}
}
public function login($username, $password){
$this->db->query('SELECT * FROM users WHERE username = :username');
//bind value
$this->db->bind(':username', $username);
$row = $this->db->single();
$hashedPassword = $row->password;
if (password_verify($password, $hashedPassword)){
return $row;
}else{
return false;
}
}
//Find user by email email is passed as argument from controller
public function findUserByEmail($email){
$this->db->query('SELECT * FROM users WHERE email = :email');
//email param binded with variabel
$this->db->bind(':email', $email);
//check if email is already registered
if ($this->db->rowCount() > 0){
return true;
}else{
return false;
}
}
}
my users controller
<?php
class Users extends Controller {
public function __construct(){
$this->userModel = $this->model('User');
}
public function register(){
$data = [
'username' => '',
'email' => '',
'password' => '',
'confirmPassword' => '',
'usernameError' => '',
'emailError' => '',
'passwordError' => '',
'confirmPasswordError' => ''
];
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
//Sanitize post data
$_POST = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING);
$data = [
'username' => trim($_POST['username']),
'email' => trim($_POST['email']),
'password' => trim($_POST['password']),
'confirmPassword' => trim($_POST['confirmPassword']),
'usernameError' => '',
'emailError' => '',
'passwordError' => '',
'confirmPasswordError' => ''
];
$nameValidation = "/^[a-zA-Z0-9]*$/";
$passwordValidation = "/^(.{0,7}|[^a-z]*|[^\d]*)£/i";
//validate username only allow letters and numbers
if (empty($data['username'])) {
$data['usernameError'] = 'Please enter a username.';
} elseif (!preg_match($nameValidation, $data['username'])) {
$data['usernameError'] = 'Name can only contain letters and numbers.';
}
if (empty($data['email'])) {
$data['emailError'] = 'Please enter an email address.';
}elseif (!filter_var($data['email'], FILTER_VALIDATE_EMAIL)){
$data['emailError'] = 'Please enter a VALID email address.';
}else{
//Check if email exists.
if ($this->userModel->findUserByEmail($data['email'])){
$data['emailError'] = 'Email address is registered to an existing account';
}
}
//Validate password min password and numbers
if (empty($data['password'])){
$data['passwordError'] = 'Please enter a password';
}elseif(strlen($data['password']) < 6){
$data['passwordError'] = 'Password must be greater than 6 characters';
} elseif (preg_match($passwordValidation, $data['password'])) {
$data['passwordError'] = 'Password MUST contain atleast one number.';
}
//validate confirm password matches password
if (empty($data['confirmPassword'])) {
$data['confirmPasswordError'] = 'Please confirm password';
}else{
if ($data['password'] != $data['confirmPassword']){
$data['confirmPasswordError'] = 'Passwords do not match';
}
}
//make sure that errors are empty
if (empty($data['usernameError']) && empty($data['emailError']) &&
empty($data['passwordError']) && empty($data['confirmPasswordError'])){
//hash password
$data['password'] = password_hash($data['password'], PASSWORD_DEFAULT);
//register user from model
if ($this->userModel->register($data)){
//redirect to login page after registering
header('location: ' . URLROOT . '/users/login');
}else{
die('Something went wrong');
}
}
}
$this->view('users/register', $data);
}
public function login(){
$data = [
'title' => 'Login Page',
'username' => '',
'password' => '',
'usernameError' =>'',
'passwordError' =>''
];
//check for post
if ($_SERVER['REQUEST_METHOD'] == 'POST'){
//sanitize post data preventing people from trying to manipulate using js
$_POST = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING );
$data = [
'username' => trim($_POST['username']),
'password' => trim($_POST['password']),
'usernameError' => '',
'passwordError' => '',
];
//validate username
if (empty($data['username'])){
$data['usernameError'] = 'Please enter a username';
}
//validate password
if (empty($data['password'])){
$data['passwordError'] = 'Please enter a password';
}
//check if all errors empty
if (empty($data['usernameError']) && empty($data['passwordError'])){
$loggedInUser = $this->userModel->login($data['username'], $data['password']);
if ($loggedInUser){
$this->createUserSession($loggedInUser);
}
}else{
$data['passwordError'] = 'Password or Username is incorrect. Please try again';
$this->view('users/login', $data);
}
}else{
$data = [
'username' => '',
'password' => '',
'usernameError' =>'',
'passwordError' =>''
];
}
$this->view('users/login', $data);
}
public function createUserSession($user){
$_SESSION['user_id'] = $user->id;
$_SESSION['username'] = $user->username;
$_SESSION['email'] = $user->email;
header('location:' . URLROOT . '/pages/index');
}
public function logout(){
unset($_SESSION['user_id']);
unset($_SESSION['username']);
unset($_SESSION['email']);
header('location:' . URLROOT . '/users/login');
}
public function Search(){
}
}
I created my own login API and here it is.
Controller/api/Authentication.php
<?php
if (!defined('BASEPATH')) exit('No direct script access allowed');
// Load the Rest Controller library
require APPPATH . '/libraries/REST_Controller.php';
require APPPATH . '/libraries/Format.php';
use Restserver\Libraries\REST_Controller;
class Authentication extends REST_Controller {
public function __construct() {
parent::__construct();
// Load the user model
$this->load->model('user');
}
public function login_post() {
// Get the post data
$email = $this->post('email');
$password = $this->post('password');
// Validate the post data
if(!empty($email) && !empty($password)){
// Check if any user exists with the given credentials
$con['returnType'] = 'single';
$con['conditions'] = array(
'email' => $email,
'password' => md5($password),
'status' => 1
);
$user = $this->user->getRows($con);
if($user){
// Set the response and exit
$this->response([
'status' => TRUE,
'message' => 'User login successful.',
'data' => $user
], REST_Controller::HTTP_OK);
}else{
// Set the response and exit
//BAD_REQUEST (400) being the HTTP response code
$this->response("Wrong email or password.", REST_Controller::HTTP_BAD_REQUEST);
}
}else{
// Set the response and exit
$this->response("Provide email and password.", REST_Controller::HTTP_BAD_REQUEST);
}
}
public function registration_post() {
// Get the post data
$first_name = strip_tags($this->post('first_name'));
$last_name = strip_tags($this->post('last_name'));
$email = strip_tags($this->post('email'));
$password = $this->post('password');
$phone = strip_tags($this->post('phone'));
// Validate the post data
if(!empty($first_name) && !empty($last_name) && !empty($email) && !empty($password)){
// Check if the given email already exists
$con['returnType'] = 'count';
$con['conditions'] = array(
'email' => $email,
);
$userCount = $this->user->getRows($con);
if($userCount > 0){
// Set the response and exit
$this->response("The given email already exists.", REST_Controller::HTTP_BAD_REQUEST);
}else{
// Insert user data
$userData = array(
'first_name' => $first_name,
'last_name' => $last_name,
'email' => $email,
'password' => md5($password),
'phone' => $phone
);
$insert = $this->user->insert($userData);
// Check if the user data is inserted
if($insert){
// Set the response and exit
$this->response([
'status' => TRUE,
'message' => 'The user has been added successfully.',
'data' => $insert
], REST_Controller::HTTP_OK);
}else{
// Set the response and exit
$this->response("Some problems occurred, please try again.", REST_Controller::HTTP_BAD_REQUEST);
}
}
}else{
// Set the response and exit
$this->response("Provide complete user info to add.", REST_Controller::HTTP_BAD_REQUEST);
}
}
public function user_get($id = 0) {
// Returns all the users data if the id not specified,
// Otherwise, a single user will be returned.
$con = $id?array('id' => $id):'';
$users = $this->user->getRows($con);
// Check if the user data exists
if(!empty($users)){
// Set the response and exit
//OK (200) being the HTTP response code
$this->response($users, REST_Controller::HTTP_OK);
}else{
// Set the response and exit
//NOT_FOUND (404) being the HTTP response code
$this->response([
'status' => FALSE,
'message' => 'No user was found.'
], REST_Controller::HTTP_NOT_FOUND);
}
}
public function user_put() {
$id = $this->put('id');
// Get the post data
$first_name = strip_tags($this->put('first_name'));
$last_name = strip_tags($this->put('last_name'));
$email = strip_tags($this->put('email'));
$password = $this->put('password');
$phone = strip_tags($this->put('phone'));
// Validate the post data
if(!empty($id) && (!empty($first_name) || !empty($last_name) || !empty($email) || !empty($password) || !empty($phone))){
// Update user's account data
$userData = array();
if(!empty($first_name)){
$userData['first_name'] = $first_name;
}
if(!empty($last_name)){
$userData['last_name'] = $last_name;
}
if(!empty($email)){
$userData['email'] = $email;
}
if(!empty($password)){
$userData['password'] = md5($password);
}
if(!empty($phone)){
$userData['phone'] = $phone;
}
$update = $this->user->update($userData, $id);
// Check if the user data is updated
if($update){
// Set the response and exit
$this->response([
'status' => TRUE,
'message' => 'The user info has been updated successfully.'
], REST_Controller::HTTP_OK);
}else{
// Set the response and exit
$this->response("Some problems occurred, please try again.", REST_Controller::HTTP_BAD_REQUEST);
}
}else{
// Set the response and exit
$this->response("Provide at least one user info to update.", REST_Controller::HTTP_BAD_REQUEST);
}
}
}
?>
and on my
Models/User.php
<?php
if (!defined('BASEPATH')) exit('No direct script access allowed');
class User extends CI_Model {
public function __construct() {
parent::__construct();
// Load the database library
$this->load->database();
$this->userTbl = 'users';
}
/*
* Get rows from the users table
*/
function getRows($params = array()){
$this->db->select('*');
$this->db->from($this->userTbl);
//fetch data by conditions
if(array_key_exists("conditions",$params)){
foreach($params['conditions'] as $key => $value){
$this->db->where($key,$value);
}
}
if(array_key_exists("id",$params)){
$this->db->where('id',$params['id']);
$query = $this->db->get();
$result = $query->row_array();
}else{
//set start and limit
if(array_key_exists("start",$params) && array_key_exists("limit",$params)){
$this->db->limit($params['limit'],$params['start']);
}elseif(!array_key_exists("start",$params) && array_key_exists("limit",$params)){
$this->db->limit($params['limit']);
}
if(array_key_exists("returnType",$params) && $params['returnType'] == 'count'){
$result = $this->db->count_all_results();
}elseif(array_key_exists("returnType",$params) && $params['returnType'] == 'single'){
$query = $this->db->get();
$result = ($query->num_rows() > 0)?$query->row_array():false;
}else{
$query = $this->db->get();
$result = ($query->num_rows() > 0)?$query->result_array():false;
}
}
//return fetched data
return $result;
}
/*
* Insert user data
*/
public function insert($data){
//add created and modified date if not exists
if(!array_key_exists("created", $data)){
$data['created'] = date("Y-m-d H:i:s");
}
if(!array_key_exists("modified", $data)){
$data['modified'] = date("Y-m-d H:i:s");
}
//insert user data to users table
$insert = $this->db->insert($this->userTbl, $data);
//return the status
return $insert?$this->db->insert_id():false;
}
/*
* Update user data
*/
public function update($data, $id){
//add modified date if not exists
if(!array_key_exists('modified', $data)){
$data['modified'] = date("Y-m-d H:i:s");
}
//update user data in users table
$update = $this->db->update($this->userTbl, $data, array('id'=>$id));
//return the status
return $update?true:false;
}
/*
* Delete user data
*/
public function delete($id){
//update user from users table
$delete = $this->db->delete('users',array('id'=>$id));
//return the status
return $delete?true:false;
}
}
?>
Now on my the XCODE I am trying to connect from xcode to the login API then there's no problem actually it successfully can login but my application is closing without any error after submitting my post request.
I'm suspecting it is because of the basic_auth?
or not
here's my source code on XCODE
#IBAction func buttonLogin(_ sender: UIButton)
{
//getting the username and password
let parameters: Parameters=[
"email": usernameTextField.text!,
"password": passwordTextField.text!,
"X-API-KEY": "xxxx-2018"
]
//making a post request
Alamofire.request(URL_USER_LOGIN, method: .post, parameters:parameters).responseJSON{
response in
//printing response
print(response)
//getting the json value from the server
if let result = response.result.value{
let jsonData = result as! NSDictionary
//if there is no error
if(!(jsonData.value(forKey:"error") as! Bool)){
//getting the user from response
//get the user from response
let user = jsonData.value(forKey: "user") as! NSDictionary
//getting user values
let userId = user.value(forKey: "id") as! Int
let userFirstName = user.value(forKey: "first_name") as! String
let userLastName = user.value(forKey: "last_name") as! String
let userEmail = user.value(forKey: "email") as! String
let userPhone = user.value(forKey: "phone") as! String
//saving user values to defaults
self.defaultValues.set(userId, forKey: "userid")
self.defaultValues.set(userFirstName, forKey: "firstname");
self.defaultValues.set(userLastName, forKey: "lastname");
self.defaultValues.set(userEmail, forKey: "useremail")
self.defaultValues.set(userPhone, forKey: "userphone")
//switching the screen
let profileViewController = self.storyboard?.instantiateViewController(withIdentifier: "ProfileViewController") as! ProfileViewController
self.navigationController?.pushViewController(profileViewController, animated: true)
self.dismiss(animated: false, completion:nil)
}
else
{
//error message in case of invalud credential
//self.labelMessage.text = "Invalid username or password"
self.showToast(message:"Invalid username or password!")
}
}
}
}
EDITED: So I found out that the basic_auth was not the cause of my app closing. I'm guessing again it is my API??
ADD INFORMATION :
Hey :) So I'm trying to check if an user has already registered or not with their email address. The email is a unique field in the database. The problem I am having is when I am checking it, (if the email exists in the table it will return false and a message will be send to the user), num_rows() always returns false even if the email entered does not exist in the table;
I don't know if there is a problem with the post, but if I comment out the email part and register, it will work and if the email is a duplicate, the 1062 error will show.
the model funtion checkEmail()
$email_address = $this->input->post('email');
$this->db->where('email', $email_address);
$result = $this->db->get('user');
if($result->num_rows() > 0){
/*
* the email already exists
* */
return false;
}
and the controller:
$checkEmail = $this->f_model->checkEmail();
if(!$checkEmail){
/*
* if email exists
* */
$msg = '<font color=red>Email already registered.</font><br />';
$this->register($msg);
}
else {
$interest = $this->f_model->enter_register_details_01();
if(!$interest) {
$msg = '<font color=red>Password and Confirm Password do not match.</font><br />';
$this->register($msg);
}
else {
$data['msg'] = $msg;
$this->load->view("registration_view_02", array('interest' => $interest,
'message' => $data));
}
}
even if the table is empty, the message with "Email already registered" appears
Thank for your help.
in checkEmail() function add an else statement
$email_address = $this->input->post('email');
$this->db->where('email', $email_address);
$result = $this->db->get('user');
if($result->num_rows() > 0){
/*
* the email already exists
*
*/
return false;
}else{
return true;
}
So after debugging my session array while logging into my website, I find that when posting a form, all session data is lost. The session data is wiped when the updateDetails and changePassword methods are called. Why is this?
session_start() is called before any data processing
Upon a POST request, session data is set and unset (but not the entire $_SESSION variable)
I use the following code to check for POST requests:
if($_SERVER['REQUEST_METHOD'] == 'POST') {
}
It only happens once: Once the session has been lost, the methods can be called without the issue occuring any further (until they lose the session through expiration or closing their browser).
index.php (part)
session_start();
$page = $_GET['p'];
$query = $_GET['q'];
$req = $_GET['req'];
$user = new User();
switch($page) {
case 'account':
if($req=="logout") {
if($user->isLoggedIn())
$user->logout();
header("Location: /?p=account");
exit();
}
else if($req=="signup") {
if($user->isLoggedIn()) {
header("Location: /?p=account");
exit();
}
else {
if($_SERVER['REQUEST_METHOD'] == 'POST') {
$form_data = array('username' => $_POST['username'],
'password' => $_POST['password'],
'password_repeat' => $_POST['password_repeat'],
'title' => $_POST['title'],
'first_name' => $_POST['first_name'],
'surname' => $_POST['surname'],
'dob_day' => $_POST['dob_day'],
'dob_month' => $_POST['dob_month'],
'dob_year' => $_POST['dob_year'],
'gender' => $_POST['gender'],
'email' => strtolower($_POST['email']),
'email_repeat' => strtolower($_POST['email_repeat']));
if($user->signup($form_data)) {
header("Location: /?p=account");
exit();
}
}
}
}
else {
if($user->isLoggedIn()==true) {
if($_SERVER['REQUEST_METHOD'] == 'POST') {
if($req=='editdetails') {
$form_data = array(
'title' => $_POST['title'],
'first_name' => $_POST['first_name'],
'surname' => $_POST['surname'],
'gender' => $_POST['gender'],
'phone' => $_POST['phone'],
'email' => strtolower($_POST['email']),
'password' => $_POST['password']
);
if($user->updateDetails($form_data)) {
header("Location: /?p=account");
exit();
}
}
else if($req=='changepassword') {
$form_data = array(
'old_password' => $_POST['old_password'],
'password' => $_POST['password'],
'password_repeat' => $_POST['password_repeat'],
);
if($user->changePassword($form_data)) {
header("Location: /?p=account");
exit();
}
}
}
$user->retrieveUserDetails();
$details=$user->getUserDetails();
}
else {
if($req) {
header("Location: /?p=account");
exit();
}
else if($_SERVER['REQUEST_METHOD'] == 'POST') {
$form_data = array('username' => $_POST['username'], 'password' => $_POST['password']);
if($user->login($form_data)) {
$user->retrieveUserDetails();
$details=$user->getUserDetails();
}
}
}
}
break;
}
user.php (part)
class User {
private $auth;
private $details;
private $session_alert;
function User() {
if(isset($_SESSION['alert']))
$this->session_alert = $_SESSION['alert'];
$this->auth = isset($_SESSION['auth']) ? $_SESSION['auth'] : null;
if(isset($this->auth)) {
$database= new Database;
if($database->checkUserSession($this->auth['user_id'],session_id())) {
$this->logged_in=true;
}
else {
$this->addSessionAlert('global','Your login session has possibly timed out, you may login again by clicking here.',true);
unset($_SESSION['auth']);
}
}
}
function login($data) {
$return = false;
$this->form = new Form($data,0);
if(!$this->form->getError()) {
$database= new Database;
$error_msg = "The username/password entered was invalid. Please check to see if they are correct and try again, or use the relevant links to recover your account.";
$salt = $database->getSaltByUsername($data['username']);
if($salt) {
$hash = $this->hashpwd($data['password'],$salt);
// Do login
$this->auth = array();
$this->auth['user_id'] = $database->checkUserByHash($data['username'],$hash);
if($this->auth['user_id']) {
session_regenerate_id();
if($database->doLogin($this->auth['user_id'],session_id())) {
$details=$database->getUserDetailsById($this->auth['user_id']);
$this->auth['first_name'] = $details['first_name'];
$_SESSION['auth']=$this->auth;
$this->logged_in=true;
$return = true;
}
else
$this->form->pushError('Something went wrong, please try again.');
}
else
$this->form->pushError($error_msg);
}
else
$this->form->pushError($error_msg);
}
return $return;
}
function logout() {
$return = false;
if(isset($this->auth)) {
$database= new Database;
if($database->clearUserSession($this->auth['user_id'],session_id())) {
unset($_SESSION['auth']);
$this->logged_in=false;
session_regenerate_id();
$return = true;
}
}
return $return;
}
function signup($data) {
$return = false;
$this->form = new Form($data,1);
if(!$this->form->getError()) {
$database= new Database;
if($database->checkUserByUsername($data['username']))
$this->form->pushError("The username entered already exists, please try again.");
else if($database->checkUserByEmail($data['email']))
$this->form->pushError("The e-mail address entered is already in use, please try again.");
else {
$dbarray = $data;
unset($dbarray['password'],$dbarray['password_repeat'],$dbarray['dob_month'],$dbarray['dob_day'],$dbarray['dob_year']);
$dbarray['dob']=date("Y-m-d", mktime(0,0,0,$data['dob_month'], $data['dob_day'], $data['dob_year']));
$dbarray['salt']=strtoupper(md5(mt_rand()));
$dbarray['hash'] = $this->hashpwd($data['password'],$dbarray['salt']);
// Do signup
$this->auth = array();
$this->auth['user_id'] = $database->newUser($dbarray);
if($this->auth['user_id']) {
session_regenerate_id();
if($database->doLogin($this->auth['user_id'],session_id())) {
$details=$database->getUserDetailsById($this->auth['user_id']);
$this->auth['first_name'] = $details['first_name'];
$_SESSION['auth']=$this->auth;
$this->logged_in=true;
}
$return=true;
}
else {
$this->form->pushError("Something went wrong, please try again.");
}
}
}
return $return;
}
function updateDetails($data) {
$return = false;
$this->form = new Form($data,2);
if(!$this->form->getError()) {
$database= new Database;
if( $database->checkUserByEmailNotById($data['email'],$this->auth['user_id']) ) {
$this->form->pushError("The e-mail address entered is already in use, please try again.");
}
else {
$salt = $database->getSaltById($this->auth['user_id']);
if($salt) {
$hash = $this->hashpwd($data['password'],$salt);
if($database->checkUserIdByHash($this->auth['user_id'],$hash)) {
$database->updateUserById($this->auth['user_id'],$data);
$return = true;
}
else
$this->form->pushError("The password entered was incorrect, please try again.");
}
}
}
return $return;
}
function changePassword($data) {
$return = false;
$this->form = new Form($data,3);
if(!$this->form->getError()) {
$database= new Database;
$salt = $database->getSaltById($this->auth['user_id']);
if($salt) {
$hash = $this->hashpwd($data['old_password'],$salt);
if($database->checkUserIdByHash($this->auth['user_id'],$hash)) {
$salt=strtoupper(md5(mt_rand()));
$hash = $this->hashpwd($data['password'],$salt);
if($database->updateSaltHashById($this->auth['user_id'],$salt,$hash)) $this->addSessionAlert('yourdetails','Your password has been changed successfully.',false);
$return = true;
}
else
$this->form->pushError("The old password entered was incorrect, please try again.");
}
}
return $return;
}
function isLoggedIn() {
return $this->logged_in;
}
function getUserDetails() {
return $this->details;
}
}
Starting a session inside a class's contructor method, just does not sound nice.
Use session_start(); at the top of the index.php page instead.
in each page where you want to use sessions you must call session_start ();
See here:
http://codex.wordpress.org/Function_Reference/wp_update_user
Note: If current user's password is being updated, then the cookies
will be cleared!
Now, why WordPress will do this is not clear, but it is clearly stated that cookies, and therefore sessions, will be removed on setting a password through wp_update_user().
Some people have found that applying an exit(); immediately after a redirect when setting the password, will prevent the cookies from being lost.