0

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?

Elikill58
  • 4,050
  • 24
  • 23
  • 45
  • I mean - fixing the CORS issue is fairly simple in PHP? Just read the request host and throw that in the CORS header? That is how it is usually done? – MikeOne Oct 14 '21 at 18:27
  • @MikeOne The PHP script isn't called, it's refused because of options request, so I edit apache config and now it's fine but some request are refused by apache and not by php – Elikill58 Oct 14 '21 at 19:12
  • Also use a post request to login users. Don't change state (return a cookie, or modify the database) on a get request. – Pieterjan Oct 21 '21 at 17:08

3 Answers3

1

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?)

0

I think your problem is not about CORS. I had a similar situation on a php backend (CodeIgniter to be specific) and the problem was on the SameSite cookie attribute. Try to add this code inside a config file or index:

setcookie($name, $value, [
    'expires' => time() + 7200,
    'path' => '/',
    'domain' => 'domain.com',
    'secure' => true,
    'httponly' => false,
    'samesite' => 'None',
]);

or for php >= 7.3:

 session_set_cookie_params([
    'lifetime' => time() + 7200,
    'path' => '/',
    'domain' => $_SERVER['HTTP_HOST'],
    'secure' => true,
    'httponly' => false,
    'samesite' => 'None'
]);

Check this question it might give you more hints.

Lu CT
  • 116
  • 3
  • Thanks, I will check it ! – Elikill58 Oct 18 '21 at 15:59
  • Update: I just upload it on real server with DNS. I update the "domain" value and then I tried. It's the same: It works with my browser but not with angular :/ (`$_COOKIE` is empty) – Elikill58 Oct 18 '21 at 17:22
  • Update 2: I tried with "Lax" as SameSite value, I also tried with `ini_set('session.cookie_samesite', 'Lax'); session_set_cookie_params(['samesite' => 'Lax']);` but it always does the same: cookie field is empty – Elikill58 Oct 18 '21 at 17:35
  • @Elikill58 be sure that **SameSite** value should be **none**, maybe there is some other configuration overriding those who are you are trying to setup. At least now you know your problems comes from the cookies. What is the version of your angular and php ? – Lu CT Oct 19 '21 at 07:33
  • Php I just upgrade to 7.3.5 to make this works. Angular i'm in 12.2.9. Also, I tried with None, Lax and Strict because i didn't find any quick explaination of what each value does – Elikill58 Oct 19 '21 at 08:08
  • @Elikill58 can you check the answer again please I added something new for your version of php. – Lu CT Oct 19 '21 at 09:39
  • Ok, should I keep session_start() before the setcookie ? – Elikill58 Oct 19 '21 at 09:51
  • @Elikill58 you should add the `session_set_cookie_params` function call on the config file if you have one , it has to be before `session_start` yes – Lu CT Oct 19 '21 at 09:54
  • That doesn't change anything, I have same issue. Do you want to go in PM (like in discord) to talk about it easier ? – Elikill58 Oct 19 '21 at 10:00
  • I also update my question to edit details. I also tried lot of things specially by using CORS credentials & your answer at same time -> same result (cookie not saved) – Elikill58 Oct 20 '21 at 08:23
  • @Elikill58 I am going to try and recreate the problem, can you also tell me the version of your apache ? and also what kind of browser are you using ? did you try another browser ? – Lu CT Oct 21 '21 at 09:22
  • Apache 2.4.39. I only try with chrome (latest version) but I tried in normal and incognito mode. Also, do you want virtualhost config or something ? Or go on discord to talk about it faster ? – Elikill58 Oct 21 '21 at 09:24
  • I began with WAMP but I also tried with apache & php installed manually on ubuntu 18 – Elikill58 Oct 21 '21 at 09:31
-1

you must add cors headers in php script

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

header('Access-Control-Allow-Methods: POST, GET, DELETE, PUT, PATCH, OPTIONS');

header("Access-Control-Allow-Headers: *");
behroozbc
  • 1,992
  • 2
  • 12
  • 25