Search code examples
phpangularsession-cookiessetcookiehttp-authentication

Failed to keep logged in angular when using php backend


I'm trying to make a login system on angular with a PhP backend.

When people login, this is the PhP script called :

// here check for good request
$account = // found the account thanks to PDO
$accountId = $account["id"];
session_start();
$_SESSION["accountId"] = $accountId;
setcookie("accountId", $accountId, [
    'expires' => time() + 86400,
    'path' => '/',
    'domain' => $_SERVER['HTTP_HOST'],
    'secure' => true,
    'httponly' => false,
    'samesite' => 'None',
]);

Then, when I want to get informations according to user, I call this script :

session_start();

if(!isset($_SESSION["accountId"]) && !isset($_COOKIE["accountId"])) {
    echo "You are not logged";
    die();
}
$accountId = isset($_SESSION["accountId"]) ? $_SESSION["accountId"] : $_COOKIE["accountId"];

// here get data
echo json_encode($accountId);

When I'm doing this in my browser, it works.

But when I'm doing it with angular, the $_SESSION and $_COOKIE are empty, so it show me "You are not logged".

My code in angular :

this.http.get<T>("http://my-url.com/script.php").toPromise().then((result) => console.log(result));

My question:

How should I use PhP/Angular request to make secure login and data-request according to logged account? Should I change of language (to Java/C#/...)* (it's not a problem for me)?

What I tried ?

  • Use { withCredentials: true } on get method on angular:
this.http.get<T>("http://my-url.com/script.php", { withCredentials: true }).toPromise().then((result) => console.log(result));

I was getting a CORS error. After updating my header (see below), I get the same result: in browser it's fine but not in angular.

  • I tried with $_SESSION and with $_COOKIE. Both are working in my browser, but not in angular.

  • I think to put the accountId in the request, each time. But it's clearly not secure, and not a very good idea...

  • Such as I had CORS issue, I add few lines to manage them:

header('Access-Control-Allow-Headers: Access-Control-Allow-Origin, Content-Type');
header('Access-Control-Allow-Origin: http://localhost:4200');
header('Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Credentials: true');
header('Content-Type: application/json, charset=utf-8');

But, it solve all CORS issues but not my session/cookie empty.

So, how can I keep session and/or cookie in Angular, like my browser does?


Solution

  • First, you can try vanilla-js function fetch("url") to deal with cookies and session storage.

    But I advise you to use tokens for API requests rather than session storage or cookies. You'll have less problems and it's easier to upgrade later.

    For example

    Of course, you need to redesign your database, and your PHP code (as the JS one). When the user is logging in, to add a bit of security, you may need to hash the password with md5() or a better method like AES, as you like, and check if this hash correspond in the database. Then, respond with a success or an error followed by the user's token (created during sign up with PHP, generally a couple of md5() and uniqid()). This token must be long to avoid bruteforces.

    Then, once the user is logged in and the Js code has the token, you have just to make API requests with this token. More often, the token is provided in a header, authorization: Bearer <token> (replace "" by the token.) It's easy to use and easy to get in PHP. (Take a look at this question : How to properly use Bearer tokens?)