0

I am currently facing problems with php sessions. I have been looking for the answer everywhere but I am afraid my problem is too specific...

The problem is the following : I am building a website with only one page index.html being displayed. This page contains a div #container whose content is replaced everytime I chose a tab in the toolbar via a route() function. It works this way:

The templates.html page contains all the info to be substituted into the page once Mustache has rendered the json array «articles». Here is the corresponding #tpl-articles (I deleted the unnecessary parts)

Now, there is a «log in» tab, which sends info to the «connexion.php» script. This script sets $_SESSION[‘user_id’] and $_SESSION['user_surname']. My problem is : if I go on another tab - say the «default» one (which is on the same index.html page) - my load_articles.php does not know the aforementioned $_SESSION variables anymore :/

Here is the «connexion.php» code :

<?php

header('Cache-Control: no-cache, must-revalidate');
header('Expires: Mon, 01 Jul 1980 05:00:00 GMT');
header('Content-type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin:*');

session_name('MODAL'); 
session_start();

ini_set('session.use_cookies', 0);
ini_set('session.use_only_cookies', 0);
ini_set('session.use_trans_sid', 1);

$msgJson = array();

$msg = array('session_id' => session_id());
array_push($msgJson, $msg);

// info from the «log in» tab
$email = strip_tags($_POST['email']);
$password = strip_tags($_POST['password']);


require('database.php');
$dbh = Database::connect();

$query  = "SELECT * FROM `users` WHERE `email`=? AND `password`=?";

$sth = $dbh->prepare($query);
$sth->execute(array($email,sha1($password)));

$tab = $sth->fetchAll(PDO::FETCH_ASSOC);

if (count($tab) == 1) {
    $_SESSION['user-id'] = $email;
    $_SESSION['user_surname'] = $tab[0][surname];
    $msg = array('success' => $_SESSION['user_surname']);
} 
else {
    $msg = array('error' => 'Fail');
}

array_push($msgJson, $msg);
echo json_encode($msgJson);
?>

And here is the load_articles.php which does not know the $_SESSION variables :

<?php

header('Cache-Control: no-cache, must-revalidate');
header('Expires: Mon, 01 Jul 1980 05:00:00 GMT');
header('Content-type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin:*'); 

session_name('MODAL');
session_start();

require 'database.php';
$dbh = Database::connect();

if ( !isset($_SESSION['user-id’])){
    $query = 'something';
    $sth = $dbh->prepare($query);
    $sth->execute();
    $result = $sth->fetchAll(PDO::FETCH_ASSOC); 
}

else {
    $query = 'something_else';
    $sth = $dbh->prepare($query);
    $sth->execute(array(
            $_SESSION['user-id'],
            $_SESSION['user-id']
            ));
    $result = $sth->fetchAll(PDO::FETCH_ASSOC);
}

echo json_encode($result);
?>

Would someone happen to understand why these session variables seem to vanish ? What am I doing wrong ? Should the index.html page be generated from a php code specifying session_start() first ? That would be a huge problem for me...

Thanks in advance for your kind help and patience, I am a beginner :/

Stelzy
  • 1
  • 1
  • 3
    **WARNING**: Writing your own access control layer is not easy and there are many opportunities to get it severely wrong. Please, do not write your own authentication system when any modern [development framework](http://codegeekz.com/best-php-frameworks-for-developers/) like [Laravel](http://laravel.com/) comes with a robust [authentication system](https://laravel.com/docs/5.4/authentication) built-in. At the absolute least follow [recommended security best practices](http://www.phptherightway.com/#security) and **never store passwords with a uselessly weak hash like SHA1 or MD5**. – tadman May 29 '17 at 22:29
  • There's a "smart quote" in the second chunk of code. Hopefully you're using a proper code editor that doesn't mangle these by design. – tadman May 29 '17 at 22:30
  • move session_start right after ` – num8er May 29 '17 at 22:31
  • @num8er `@` seriously? You need to handle errors not hide them – E_p May 29 '17 at 22:32
  • @E_p (: in case of UX it's better hide errors and give appropriate response to user. Also user says he is beginner. So it's dirty fix for beginner (: – num8er May 29 '17 at 22:35
  • @E_p that's how You help people? Just asking questions to me? – num8er May 29 '17 at 22:47
  • @num8er Exactly as I found that your answer teaches bad practices, nothing personal. – E_p May 29 '17 at 22:52
  • @E_p when someone begins to code it's better to remove all stopping moments to make him/her progress. That's how I teach to make first steps on development. But of course I'm explaining the meaning of @ sign. – num8er May 29 '17 at 22:56
  • 1
    @tadman Thanks for telling me ! Unfortunately it was just a mistake I made when copying the chunk of code :/ – Stelzy May 30 '17 at 20:26
  • @num8er Thank you for your idea ! But this did not solve the problem, the php session variables still disappear... – Stelzy May 30 '17 at 20:29
  • I think You should enable `display_errors` and set error reporting settings to see if there is any issue. – num8er May 30 '17 at 20:31

2 Answers2

0

Your session functions should be placed on the first lines in your page. So, bring session_start() and the session functions on the top of your pages, e.g. over all other header codes.

Please see this, this and this answer.

Good luck.

0

The problem is in here:

header('Cache-Control: no-cache, must-revalidate');
header('Expires: Mon, 01 Jul 1980 05:00:00 GMT');
header('Content-type: application/json; charset=utf-8');

Just remove them.

PHP code is not cached on browser to worry about telling to browser that it must be auto-expired



Bonus:

try this code

<?php

ini_set('display_errors', 1);
error_reporting(E_ALL);

session_start();
header('Access-Control-Allow-Origin:*'); 

require 'database.php';
$dbh = Database::connect();

function responseJSON($data, $exit = true) {
  header('Content-type: application/json');
  echo json_encode($data);
  if($exit) exit(0);
}  

$userId = isset($_SESSION['user-id']) ? $_SESSION['user-id'] : null;

if($userId) {
   $query = 'something_else';
   $sth = $dbh->prepare($query);
   $sth->execute([$userId, $userId]);
   responseJSON($sth->fetchAll(PDO::FETCH_ASSOC));
}


$query = 'something';
$sth = $dbh->prepare($query);
$sth->execute();
responseJSON($sth->fetchAll(PDO::FETCH_ASSOC));
num8er
  • 18,604
  • 3
  • 43
  • 57
  • Thanks a lot @num8er ! I deleted all these headers but the 'Content-type' one, without whom my page does not understand what php sends back... I tried your code without the header('Access-Control-Allow-Origin:*') but I get an error saying: "XMLHttpRequest cannot load http://localhost:8888/uptimo/load_articles.php. Origin http://localhost:63342 is not allowed by Access-Control-Allow-Origin." ... – Stelzy May 30 '17 at 20:35
  • ... so I wrote a .htaccess file stipulating " Header set Access-Control-Allow-Origin * Header set Access-Control-Allow-Credentials true " but this does not solve my problem :/ – Stelzy May 30 '17 at 20:37
  • How about to add cors header after session start? – num8er May 30 '17 at 20:39