Search code examples
phpangularpostpdohttp-status-code-403

Angular 5 to PHP POST returns always 403


I had a working version but after some changes (I've no clue what) it doesn't work anymore. Now I brought everything back to a very simple application to make sure nothing else is in it's way. Yes, I know this is bad practice code, but that doesn't matter I just want to know what is wrong with this.

Now my code, it's not everything but I think this is everything you need to get an idea what my code does.

Angular:

Form:

<form>
  <table cellspacing="0">
    <tr>
      <td>
          <input placeholder="Username" class="form-control" [(ngModel)]="username" name="username" required>
      </td>
    </tr>
    <tr>
      <td>
        <input placeholder="Password" class="form-control" [(ngModel)]="password" type="password" name="password" required>
      </td>
    </tr></table>
</form>
<button mat-raised-button (click)="loginUser()" class="btn btn-primary" color="primary">Login</button>

Component:

loginUser() : void {
    let result = this.LoginService.loginUser(this.username, this.password);
    if (result === false) {
      this.wrongLoginNotification = 'Je hebt de onjuiste inloggegevens gebruikt!';
    }
  }

Service:

  private loginUrl = 'http://www.url.nl/path/api/?login=true';


  loginUser(username: string, password: string): boolean {
    let auth = {username: username, password: password};
    let authJson = JSON.stringify(auth);

    this.http.post(this.loginUrl, authJson)
      .subscribe(
        data => {
          this.router.navigate(["home"]);
          return true;
        },
        err => {
          return false;
        }
      );

    return false;
  }

This posts to server:

{password: "TEST", username: "TEST1"}

PHP script is very easy and is nothing more then:

error_reporting(E_ALL);
header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json; charset=UTF-8");

$servername = ""; // Changed this of course ;-)
$username = ""; // Changed this of course ;-)
$password = ""; // Changed this of course ;-)
$dbName = ""; // Changed this of course ;-)
$conn = null;

try
{
  $conn = new PDO("mysql:host=$servername;dbname=$dbName", $username, $password);
  // set the PDO error mode to exception
  $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $e)
{
  echo "Connection failed: " . $e->getMessage();
  header("HTTP/1.1 404");
}

if (isset($_GET['login'])) {
  echo 'Test';
}

Now the PHP api (on same domain/url) returns:

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access /myurl/api/
on this server.<br />
</p>
<p>Additionally, a 403 Forbidden
error was encountered while trying to use an ErrorDocument to handle the request.</p>
</body></html>

What have I tried?

  • I did check the premissions on folders: 755, files: 644.
  • GET is still working, POST not.
  • Read several posts on StackOverflow. Did try several things with .htaccess file such as adding:

    Header add Access-Control-Allow-Origin: * Header add Access-Control-Allow-Methods: "GET,POST,OPTIONS,DELETE,PUT"

I'm also in contact with my hosting. Anyone has any suggestions? I do see lots of questions posted on this subject and everyone has an other solution. What is the best way to filter this and get to the right point? I'm now just trying things without following a list or something that maybe gets me to the solution.

Any help would be very welcome!


Solution

  • Header needs to be called before any other output. So your try/catch block looks something like this:

    try
    {
      $conn = new PDO("mysql:host=$servername;dbname=$dbName", $username, $password);
      // set the PDO error mode to exception
      $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    }
    catch(PDOException $e)
    {
      header("HTTP/1.1 404");
      echo "Connection failed: " . $e->getMessage();
    }
    

    EDIT: Also try to remove authJSON and use auth instead. Just pass that JSON object directly.