I am using PhalconPHP, and trying to implement an authentication service. My front-end is an AngularJS 5 application that utilizes this service that is on a subdomain. (My front end is found at www.MyWebsite.com, and my service is found at service.MyWebsite.com) So far I have implemented the following method to start my session.
$di->setShared('session', function () {
$session = new Session();
$session->start();
return $session;
});
Then, I call my loginUser
method when the user posts their username/password to the service
public function loginUser(array $userData){
$username = $userData['username'];
$password = $userData['password'];
$user = Users::findFirst(
[
'conditions' => '(username = :username:) AND password = :password:',
'bind' => [
'username' => $username,
'password' => $password,
],
'columns' => ['users_id AS id, first, last, username, email']
]
);
$this->_registerSession($user);
return $user->toArray();
}
After a user attempts login, I stash the username and user ID into the session using the _registerSession($user)
method.
private function _registerSession($user){
$this->session->set(
"auth",
[
"id" => $user->id,
"username" => $user->username,
]
);
}
At this point, the user is able to successfully log in, as I am able to return the users ID, first and last name, username, and email, with the username and ID stored in my sessions auth
configuration.
The issue that I have is that when I refresh my page, the User gets logged out.
The first thing I figured was that since my Angular app is an SPA, so refreshing the page will drop the current global variable I have set to store information on the current user. So, in order to fix that, I think I need to re-pull the information from the server based on the session.
So, I've implemented a method for getCurrentUser()
public function getCurrentUser(){
$id = $this->session->auth["id"];
if($id == null){
return null;
}
$user = Users::findFirst(
[
'conditions' => 'users_id = :id:',
'bind' => [
'id' => $id,
],
'columns' => "users_id AS id, first, last, username, email",
]
);
$this->_registerSession($user);
return $user->toArray();
}
And when I test this using Postman, I am able to post to the login endpoint, and then anytime in the next 30 minutes if I make a call to getCurrentUser
, I end up getting my values back.
BUT when I try to do this in the AngularJS app, I always get a null value on $id
which tells me that it's not able to pull/doesn't see the auth
in the session variable.
I've verified that the PHPSESSIONID being set in the cookies isn't changing, so the sessionID should still be the same... So why can't it pull that ID from the existing session in the Angular app, but it can when I make calls directly from PostMan?
EDIT Someone mentioned that it may be due to a CORS. They deleted their answer, but just to show my setup for that, here is the index file where I am attaching certain headers
if (isset($_SERVER['HTTP_ORIGIN'])) {
// Decide if the origin in $_SERVER['HTTP_ORIGIN'] is one
// you want to allow, and if so:
header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Max-Age: 86400'); // cache for 1 day
}
// Access-Control headers are received during OPTIONS requests
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']))
// may also be using PUT, PATCH, HEAD etc
header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']))
header("Access-Control-Allow-Headers:{$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");
exit(0);
}
It may still have something to do with CORS, but from my limited knowledge I don't see that being the case.
Are you sure that angular 5 is making requests with withCredentials: true
?