I am aware other questions like this one exist, i have failed to implement any of those successfully, meaning none have worked, whether due to a fault of my own or their inherent impotency to solving this problem.
The environment :
I am serving the php project with php -S 127.0.0.1:8080
and have a react front end started on the default port (3000) with npm start
. I am using axios for making the request to the server.
The relevant code :
I have 2 files that really matter :
- LoginPage.js is where my react code is, I am making 2 requests, the first one is to mimic authentication and start the session and the second request is to check if the session is still alive:
useEffect(() => { axios({ method: "get", url: "http://localhost:8080/phpfolder/test1page.php?username=username", dataType: "JSON", }) .then((response) => { console.log("response here", response.data); setUserName(response.data); }) .catch((error) => { console.log(error); }); }, []); useEffect(() => { if (userName !== "") { axios({ method: "get", url: "http://localhost:8080/phpfolder/test1page.php", dataType: "JSON", }) .then((response) => { console.log("response here", response.data); }) .catch((error) => { console.log(error); }); } }, [userName]);
- test1page.php is where my php code is :
<?php session_start(); header("Access-Control-Allow-Origin: *"); header('Access-Control-Allow-Headers: Content-Type'); if (isset($_GET['username'])) { $_SESSION['username'] = $_GET['username']; // echo $_SESSION['username']; } if(!isset($_SESSION['username'])){ echo 'you are not logged in'; }else{ echo 'you are logged in'; header('Content-type: application/json'); echo json_encode($_SESSION); } ?>
The problem :
My problem is that, while the first request authenticates no problem :
you are logged in{"username":"username"}
The second request does not find a live session :
you are not logged in
Tried Solutions/Debugging :
I have tried many solution, including setting withCredentials: false
and true
. Setting it to true causes a Cors error. I have added and removed all kinds of headers from the php file (some for Cors, and some to try to solve this problem) :
header("Access-Control-Allow-Headers: *"); header("Access-Control-Allow-Origin: http://localhost:3000"); header('Access-Control-Allow-Origin: *'); header("Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE"); header("Access-Control-Allow-Headers: Content-Disposition, Content-Type, Content-Length, Accept-Encoding"); header("Content-type:application/json"); header("connection:keep-alive");
I have tried postman and sending a request to start the session, then another to check if it is alive works just fine :
- First request :
- Second request :
Advertisement
Answer
I found the solution. A detailed explanation can be found in this article about Cors. The relevant part is in the Credentials and Cors section. The short answer is that you have to set the withcredentials flag to true, which will cause a Cors error issue, which you can then fix by adding the appropriate headers in the backend :
header("Access-Control-Allow-Origin: http://localhost:3000"); header("Access-Control-Allow-Credentials: true");
So this is how my pages look now that everything is working fine :
- LoginPage.js :
useEffect(() => { axios({ method: "get", url: "http://localhost:8080/phpfolder/test1page.php?username=username", dataType: "JSON", withcredentials: true }) .then((response) => { console.log("response here", response.data); setUserName(response.data); }) .catch((error) => { console.log(error); }); }, []); useEffect(() => { if (userName !== "") { axios({ method: "get", url: "http://localhost:8080/phpfolder/test1page.php", dataType: "JSON", withcredentials: true }) .then((response) => { console.log("response here", response.data); }) .catch((error) => { console.log(error); }); } }, [userName]);
test1page.php :
<?php session_start(); header("Access-Control-Allow-Origin: http://localhost:3000"); // cannot be a wildcard, you have to specify the name of the domain making the request here. header('Access-Control-Allow-Headers: Content-Type'); header("Access-Control-Allow-Credentials: true"); // add this header if (isset($_GET['username'])) { $_SESSION['username'] = $_GET['username']; // echo $_SESSION['username']; } if(!isset($_SESSION['username'])){ echo 'you are not logged in'; } else { echo 'you are logged in'; header('Content-type: application/json'); echo json_encode($_SESSION); } ?>