1

I am using angular 6 for frontend and PHP for backend (WAMP) and I want to make a login system. When someone enters valid credentials I want him to get redirected to http://localhost:4200/home

I have auth.php which sets the session variables when someone enters valid username/password and verify.php to check if the session variables are set. Although the app redirects me to home, verify.php can not see the session variables.

Those are my files:

login-form.component.ts

loginUser(event) {
const target = event.target;
const username = target.querySelector('#username').value;
const password = target.querySelector('#password').value;

this.Auth.login(username, password).subscribe(data => {
  if(data.success) {
    this.router.navigate(['/home']);
  }
  else {
    window.alert(data.message);
  }
});
}

which takes the username and password from html and sends it to the service

auth.service.ts

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http'

interface myData {
  success: boolean,
  message: string
}

@Injectable({
  providedIn: 'root'
})
export class AuthService {

  constructor(private http: HttpClient) { }

  login(username, password) {
     return this.http.post<myData>('http://localhost/angular6-app/api/auth.php', {username, password}, 
    {
      headers : {
          'Content-Type' : 'application/x-www-form-urlencoded; charset=UTF-8'
      } 
    })

  }

auth.php

include 'config.php'; 
header('Access-Control-Allow-Origin: http://localhost:4200'); 

$postdata = file_get_contents("php://input");
if(isset($postdata) && !empty($postdata)) {

    $request = json_decode($postdata);
    $username = $request->username;
    $password = $request->password;
    $sql = "select * from user where username = '$username'";
    $result = $conn->query($sql);              
    $row = $result->fetch_assoc();

    if($row['username'] == $username && password_verify($password, $row['password'])) //kanei verify me to hash pou exei ginei
        {
            $_SESSION['username'] = $username;  
            $_SESSION['loggedin'] = true;
            ?>
            {
                "success": true,
                "message": "You have logged in"
            }
            <?php
        }
    else {
        ?>
        {
            "success": false,
            "message": "Invalid credentials"
        }
        <?php
        }
}

?>

and finally verify.php

<?php
session_start();
header('Access-Control-Allow-Origin: http://localhost:4200');

if (isset($_SESSION['loggedin'])) {
    ?>
    {
        "success": true,
        "message": "You have the right."

    } 
    <?php
}
else {
    ?>
    {
        "success": false,
        "message": "You DONT have the right."
    }
    <?php
}

?>

My home.component.ts has this class and I want to display in html "You have the right" but it displays "You DONT have the right" because the variable loggedin is undefined.

export class HomeComponent implements OnInit {

  message = "Loading..."

  constructor(private user: UserService) { }

  ngOnInit() {
    this.user.getSomeData().subscribe(data => {
      this.message = data.message;
    })
  }

getSomeData() is implemented in user.service.ts

getSomeData() {
    return this.http.get<myData>('http://localhost/angular6-app/api/verify.php');
  }

Is there a way to fix this problem with session or do I have to use another method of checking in angular?

Thank you.

sniperalex117
  • 79
  • 3
  • 9

4 Answers4

3

You can't set SESSION on one domain and use on other domain, From your code it's clear you are using two different port, if you want to use sessions javascript and PHP must be on the same Domain/ports.

If you want to use different domains/ports then you have to find other ways like token based auth, i.e in auth.php after successful login create a token which will be saved in your database, send back that token in your successful response.

in your angular save that token to storage ( or wherever you prefer ) and retrieve use data from your PHP API using that token.

so when you do a call in user.service.ts your URL should contain the token

YOUR_TOKEN = '1234'//received after successfull login and saved in local storage
return this.http.get<myData>('http://localhost/angular6-app/api/verify.php?token='+YOUR_TOKEN);

in your verify.php

$token = $_GET['token'];
// check if token is valid in your database and send response

p.s when logout make sure to either expire or delete token from angulare storage and database.

user969068
  • 2,818
  • 5
  • 33
  • 64
  • 1
    Thanks for your advice! By "save that token to storage" you mean something like local storage or session storage? – sniperalex117 Oct 24 '18 at 11:33
  • you can use either local or sessionStorage in angulare, it depends on your needs, also you can instead store full session of user instead creating token, it was just to give you an idea. Now it all depends how you use user data – user969068 Oct 24 '18 at 11:35
1

You will get your session values once you build ngApp and make it live and keep your app and API in the same directory, you can use the same above method. Because you are going to access the API with same port/domain.

J. Scott Elblein
  • 4,013
  • 15
  • 58
  • 94
Gopala Raja Naika
  • 2,321
  • 23
  • 18
0

I had the same issue working on React and PHP locally, both using localhost but on different ports. This answer helped me.

PHP sessions are stored on cookies, and when making cross-domain (or in this case cross-port) requests those cookies are not shared.

In your first login call to PHP, you need to return the session ID using session_id() and store this somewhere on your app.

auth.php

//.....
{
    "session_id": session_id(),//<- Return sid and store it on app
    "success": true,
    "message": "You have logged in"
}
//.....

Then, when making furter calls to PHP, make sure to pass it the same session id. You can then use session_id() again to set the id to the one you passed, which will keep the last session active:

verify.php

<?php
$postdata = file_get_contents("php://input");
if(isset($postdata) && !empty($postdata)) {
    $request = json_decode($postdata);
    if ($request->session_id) {
        session_id($request->session_id);
    }
}
session_start();
header('Access-Control-Allow-Origin: http://localhost:4200');

if (isset($_SESSION['loggedin'])) {
    $json['session_id'] = session_id();//Return sid and store it on your app for future calls
    $json['success'] = true;
    $json['message'] = "You have the right.";
} else {
    $json['success'] = false;
    $json['message'] = "You DONT have the right.";
}

echo json_encode($json);
ouflak
  • 2,458
  • 10
  • 44
  • 49
David B
  • 13
  • 4
0

I recently ran into this issue when trying to use angular-cli and xampp together. I worked around it by using

ng build

instead of

ng serve

here is build command I used.

ng build --outputPath="C:\development\xampp\htdocs\cars" --watch

This works similar to ng serve the only difference being I am serving angular app out of the xampp server instead of the angular cli server.

One more item to keep in mind is that my angular app is running inside 'cars' folder so we need to update the 'baseref' inside the index.html file in the angular application. Here is the baseref code

<base href="./">

Otherwise when we navigate to

http://localhost/cars/

it tries to pick up all the css and js files from htdocs folder

ecosystem31
  • 276
  • 2
  • 4