I am using the following slim session manager(https://github.com/bryanjhv/slim-session). I have separate functions for login, logout and user_data.
$app->post("/login", function() use ($app)
{
$input = $app->request()->getBody();
$input = json_decode($input);
try
{
if ($input->username && $input->password)
{
$user = Model::factory('Users')->where("username",$input->username)->where("password",md5($input->password))->find_one();
$session = new \SlimSession\Helper;
//set session
$session->set('userid', $user->id);
$status = 'success';
$message = 'Logged in successfully.';
}
else
{
$status = 'danger';
$message = 'Could not log you in. Please try again.';
}
}
catch (Exception $e)
{
$status = 'danger';
$message = $e->getMessage();
}
$response = array(
'status' => $status,
'message' => $message,
);
$app->response()->header("Content-Type", "application/json");
echo json_encode($response);
});
$app->post("/logout",function() use ($app)
{
try {
$session = new \SlimSession\Helper;
$session::destroy();
$status = 'success';
$message = 'You have been logged out successfully';
}
catch (Exception $e)
{
$status = 'danger';
$message = $e->getMessage();
}
$response = array(
'status' => $status,
'message' => $message
);
$app->response()->header("Content-Type", "application/json");
echo json_encode($response);
});
$app->get("/user_data", function() use ($app)
{
try
{
$session = new \SlimSession\Helper;
//get session
$userid = $session->get('userid');
$_SESSION['userid'] = $userid;
if ($_SESSION['userid'])
{
$users = Model::factory('Users')->where('id',$_SESSION['userid'])->find_one();
$response = array(
'id'=>$users->id,
'username'=>$users->username,
'email'=>$users->email,
'phone_number'=>$users->phone_number,
'password'=>$users->password,
'type'=>$users->type,
'credits'=>$users->credits,
'profile_picture'=>$users->profile_picture,
);
}
else
{
$status = "danger";
$message = 'You need to be logged in to do that.';
$response = array(
'status' => $status,
'message' => $message
);
}
}
catch (Exception $e)
{
$status = "danger";
$message = $e->getMessage();
$response = array(
'status' => $status,
'message' => $message
);
}
$app->response()->header("Content-Type", "application/json");
echo json_encode($response);
});
The problem I am having is that when the user logs in I set a session variable in the /login function. But when the session variable i set in login function isn't being retrieved in the /user_data function.
Anyone knows whats going on?
Have you started session with session_start() ?
Correct logic to check session is as follows:
if (isset($_SESSION['userid']))
{
// session exists
// do further work
}
Related
I setup a PHP API on Slim 3 framework. I have followed its documents. I am sending POST request from POSTMAN to check it on localhost, being run by XAMPP. But it is giving errors that required parameters are empty or missing though I am giving all the parameters in the POST request, as shown in the attached photo. enter image description here
I have checked the related code in index.php and Dboperations.php , and didn't find any error. The code is also written here:
$app = new \Slim\App([
'settings'=>[
'displayErrorDetails'=>true
]
]);
$app->post('/createuser', function(Request $request, Response $response){
if(!haveEmptyParameters(array('firstname', 'surname', 'email', 'fanID', 'deviceLocation'), $request, $response)){
$request_data = $request->getParsedBody();
$firstname = $request_data['firstname'];
$surname = $request_data['surname'];
$email = $request_data['email'];
$fanID = $request_data['fanID'];
$deviceLocation = $request_data['deviceLocation'];
$db = new DbOperations;
$result = $db->createUser($firstname, $surname, $email, $fanID, $deviceLocation);
if($result == USER_CREATED){
$message = array();
$message['error'] = false;
$message['message'] = 'User created successfully';
$response->write(json_encode($message));
return $response
->withHeader('Content-type', 'application/json')
->withStatus(201);
}else if($result == USER_FAILURE){
$message = array();
$message['error'] = true;
$message['message'] = 'Some error occurred';
$response->write(json_encode($message));
return $response
->withHeader('Content-type', 'application/json')
->withStatus(422);
}else if($result == USER_EXISTS){
$message = array();
$message['error'] = true;
$message['message'] = 'User Already Exists';
$response->write(json_encode($message));
return $response
->withHeader('Content-type', 'application/json')
->withStatus(422);
}
}
return $response
->withHeader('Content-type', 'application/json')
->withStatus(422);
});
function haveEmptyParameters($required_params, $request, $response){
$error = false;
$error_params = '';
$request_params = $request->getParsedBody();
foreach($required_params as $param){
if(!isset($request_params[$param]) || strlen($request_params[$param])<=0){
$error = true;
$error_params .= $param . ', ';
}
}
if($error){
$error_detail = array();
$error_detail['error'] = true;
$error_detail['message'] = 'Required parameters ' . substr($error_params, 0, -2) . ' are
missing or empty';
$response->write(json_encode($error_detail));
}
return $error;
}
$app->run();
I have used the same parameters e.g firstname,surname etc in Dboperations.php file so I am not attaching the code from that php script.Kindly consider guiding me on this problem.
This is more like a debugging problem than an actual question. I have a login script in PHP which should check for user information from a local database and if present, then display them. Or else, redirect them to the Google OAuth2 Login process. The following php files concern the login flow :
google_login.php
<?php
error_reporting(E_ALL); ini_set('display_errors', 1);
require('http.php');
require('oauth_client.php');
require('../config.php');
require('StructuredQuery.php');
define("SCOPE", 'https://www.googleapis.com/auth/userinfo.email '.
'https://www.googleapis.com/auth/userinfo.profile' );
$client = new oauth_client_class;
$sq= new StructuredQuery();
// set the offline access only if you need to call an API
// when the user is not present and the token may expire
$client->offline = FALSE;
$client->debug = false;
$client->debug_http = true;
$client->redirect_uri = GOOGLE_REDIRECT_URL;
$client->client_id = GOOGLE_CLIENT_ID;
$application_line = __LINE__;
$client->client_secret = GOOGLE_CLIENT_SECRET;
if (strlen($client->client_id) == 0 || strlen($client->client_secret) == 0)
die('Please go to Google APIs console page ' .
'http://code.google.com/apis/console in the API access tab, ' .
'create a new client ID, and in the line ' . $application_line .
' set the client_id to Client ID and client_secret with Client Secret. ' .
'The callback URL must be ' . $client->redirect_uri . ' but make sure ' .
'the domain is valid and can be resolved by a public DNS.');
/* API permissions
*/
$client->scope = SCOPE;
if (($success = $client->Initialize())) {
if (($success = $client->Process())) {
if (strlen($client->authorization_error)) {
$client->error = $client->authorization_error;
$success = false;
} elseif (strlen($client->access_token)) {
$success = $client->CallAPI(
'https://www.googleapis.com/oauth2/v1/userinfo', 'GET', array(), array('FailOnAccessError' => true), $user);
}
}
$success = $client->Finalize($success);
}
if ($client->exit)
exit;
if ($success) {
// Now check if user exist with same email ID
try {
$result = $sq->getUserInfo($user->id);
if ($result["count"] > 0) {
// User Exist
$_SESSION["name"] = $result["name"];
$_SESSION["email"] = $result["email"];
$_SESSION["clevel"]=$result["clevel"];
$_SESSION["new_user"] = "no";
} else {
// New user, Insert in database
$result = $sq->putNewUserInfo($user->id,$user->name,$user->email);
if ($result===true) {
$_SESSION["name"] = $user->name;
$_SESSION["email"] = $user->email;
$_SESSION["new_user"] = "yes";
$_SESSION["e_msg"] = "";
}
}
$_SESSION["login_type"]="Google";
} catch (Exception $ex) {
$_SESSION["e_msg"] = $ex->getMessage();
}>
$_SESSION["user_id"] = $user->id;
} else {
$_SESSION["e_msg"] = $client->error;
}
header("Location: ".ROOT_DIR."homepage.php");
exit;
?>
StructuredQuery.php
<?php
error_reporting(E_ALL); ini_set('display_errors', 1);
require_once 'config.php';
class StructuredQuery{
var $opt;
var $pdo;
function __construct(){
$opt = [
PDO::ATTR_PERSISTENT => FALSE,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
];
$this->pdo = new PDO(DB_DRIVER.":host=".DB_SERVER.";dbname=".DB_NAME, DB_SERVER_USERNAME, DB_SERVER_PASSWORD, $opt);
}
// Cross Site Script & Code Injection Sanitization
function xss_cleaner($input_str) {
$return_str = str_replace( array('<',';','|','&','>',"'",'"',')','('), array('<',':','|','&','>',''','"',')','('), $input_str );
$return_str = str_ireplace( '%3Cscript', '', $return_str );
return $return_str;
}
//SQLInjection detect
function sql_injection_detect($input_query){
try{
$blacklist=array('SELECT','WHERE','UPDATE','DELETE','INSERT','FROM','DROP','MERGE','SET','INSERT','REMOVE','REPLACE','QUERY');
$err_level=0;
foreach($blacklist as $blacklist_item){
if(stripos($input_query,$blacklist_item)!==false){
$err_level++; //Counter for number of blacklist words used. 2 means dangerous. Terminate immediately.
if($err_level==2){
die('Was that an IT joke? Cause I am a 12th grader, not an IT Pro.');
}
}
}
return true;
}catch(Exception $e){
echo 'Exception Occured:',$e->getMessage(),"\n";
die('You\'ve been Terminated');
}
}
function getUserInfo($user_id){
$user_id=xss_cleaner($user_id);
if(sql_injection_detect($user_id)){
$query=$pdo->prepare("select statement");
$query->bindParam(":user_id",$user_id,PDO::PARAM_STR);
$query->execute();
$result=$query->fetch();
$result["count"]=$query->rowCount();
return $result;
}
}
function putNewUserInfo($user_id,$name,$email){
$user_id=$this->xss_cleaner($user_id);
$name=xss_cleaner($name);
$email=xss_cleaner($email);
if(sql_injection_detect($user_id) && sql_injection_detect($name) && sql_injection_detect($email)){
$query=$pdo->prepare("insert statement");
$query->bindParam(":user_id",$user_id,PDO::PARAM_STR);
$query->bindParam(":name",$name,PDO::PARAM_STR);
$query->bindParam(":email",$email,PDO::PARAM_STR);
$query->execute();
return true;
}else{
return false;
}
}
function modifyUserInfo($user_id,$name,$email,$clevel){
$user_id=xss_cleaner($user_id);
$name=xss_cleaner($name);
$email=xss_cleaner($email);
$clevel=xss_cleaner($clevel);
if(sql_injection_detect($user_id) && sql_injection_detect($name) && sql_injection_detect($email) && sql_injection_detect($clevel)){
$query=$pdo->prepare("update statement");
$query->bindParam(":user_id",$user_id,PDO::PARAM_STR);
$query->bindParam(":name",$name,PDO::PARAM_STR);
$query->bindParam(":email",$email,PDO::PARAM_STR);
$query->bindParam(":clevel",$clevel,PDO::PARAM_INT);
$query->execute();
return true;
}else{
return false;
}
}
}
Now the issue that bothers me is this- whenever i press Login With Google, it redirects to google_login.php, well and fine. And then, directly to the homepage as if I am already logged in even though I am not. Even weirder is that it displays my e-mail and my username as blank, even though it says that I am an existing user.
P.S. No, the database does not contain any blank entries and it works fine, I double-checked.
Im trying display a message when you have nothing to delete in the database instead of showing a error that says you have a null value
public function destroy($customer_id)
{
$customer_response = [];
$errormsg = "";
$customer = Customer::find($customer_id);
$result = $customer->delete();
try{
//retrieve page
if ($result){
$customer_response['result'] = true;
$customer_response['message'] = "Customer Successfully Deleted!";
}else{
$customer_response['result'] = false;
$customer_response['message'] = "Customer was not Deleted, Try Again!";
}
return json_encode($customer_response, JSON_PRETTY_PRINT);
}catch(\Exception $exception){
dd($exception);
$errormsg = 'No Customer to de!' . $exception->getCode();
}
return Response::json(['errormsg'=>$errormsg]);
}
the try/catch method is not working compared to my previous store function that is working
Read up further on findOrFail. You can catch the exception it throws when it fails to find.
try {
$customer = Customer::findOrFail($customer_id);
} catch(\Exception $exception){
dd($exception);
$errormsg = 'No Customer to de!' . $exception->getCode();
return Response::json(['errormsg'=>$errormsg]);
}
$result = $customer->delete();
if ($result) {
$customer_response['result'] = true;
$customer_response['message'] = "Customer Successfully Deleted!";
} else {
$customer_response['result'] = false;
$customer_response['message'] = "Customer was not Deleted, Try Again!";
}
return json_encode($customer_response, JSON_PRETTY_PRINT);
this is a controller where i'm creating a session :
public function login(){
if(isset($_POST)){
$res = $this->register_model->loginUser();
if($res['result'] === true){
// declare session variables
$user = $res['info']; // array containing user information
// set session variables
$_SESSION['storeId'] = $user->str_id;
$_SESSION['sName'] = $user->str_nme;
$_SESSION['sId'] = $user->str_identifier;
$_SESSION['hash'] = $user->hash;
$res['info'] = null;
}
} else {
$res = array('result'=>false,'msg'=>'Login failed. Please try again');
}
echo json_encode($res);
}
and this is a controller where i retrieve a session
Try this
public function login(){
if(isset($_POST)){
$res = $this->register_model->loginUser();
if($res['result'] === true){
// declare session variables
$user = $res['info']; // array containing user information
// set session variables
$this->load->library('session');
$newdata = array(
'storeId' => $user->str_id,
'sName' => $user->str_nme,
'sId' => $user->str_identifier,
'hash' => $user->hash,
'info' => null,
'logged_in' => TRUE,
);
$this->session->set_userdata($newdata);
}
} else {
$res = array('result'=>false,'msg'=>'Login failed. Please try again');
}
echo json_encode($res);
}
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.