React + Codeigniter Response for preflight is invalid - php

I have a website that was built using codeigniter MVC but following modern trends I'm trying to create a frontend based on react. I still want to use original codeigniter framework and controllers but instead or rendering views I want it to return plain JSON. Currently I'm stuck on being unable to send requests from react application that runs in debug mode on localhost:3000 to my codeigniter api that is running on apache http://mywebsite:80
this is how I'm initiating request:
fetch("http://mywebsite/Api" + route + '/', {
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
method: "POST",
redirect: 'follow',
body: JSON.stringify(data),
dataType : 'json'
})
This is the error I'm getting in a console:
Failed to load http://mywebsite/ApiAuth/login/: Response for preflight
is invalid (redirect)
My php page sends the following back:
header('Content-Type: application/json;charset=UTF-8');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: DELETE, HEAD, GET, OPTIONS, POST, PUT');
header('Access-Control-Allow-Headers: Content-Type, Content-Range, Content-Disposition, Content-Description');
header('Access-Control-Max-Age: 1728000');
Console outputs:
Request URL: http://mywebsite/ApiAuth/login/
Request Method: OPTIONS
Status Code: 302 Found
Remote Address: [::1]:80
Referrer Policy: no-referrer-when-downgrade

Was able to fix the issue by setting Apache response headers and redirect method like this:
#Redirect for CORS Preflight request
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=200,L]
#Set headers to access CORS Requests / allowing localhost only
Header always add Access-Control-Allow-Origin "*"
Header always add Access-Control-Allow-Headers "origin, x-requested-with, content-type"
Header always add Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"

Related

CORS policy: No 'Access-Control-Allow-Origin' from same server

I have a problem with CORS policy. Trying access to php file in the same server of ajax code, but have the CORS error.
await $.ajax({
url: '/includes/paystripe.php',
type: 'POST',
crossDomain: true,
data: {api_key_stripe: api_key_stripe, customer_id:customer_id},
success: function(data){
}
});
Error:
Access to XMLHttpRequest at 'https://www.subDomain.domain.com/includes/paystripe.php' (redirected from 'https://subDomain.domain.com/includes/paystripe.php') from origin 'https://subDomain.domain.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
If I work on localhost, don't have this problem, it's posible poblem with server config?
EDIT:
If I put headers on paystripe.php get a 500 error (only on server, not on localhost):
header('Access-Control-Allow-Origin: *');
header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept");
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE');

Angular PHP Authorization Header API Call Fails

I am working on a login page functionality in a SPA built with Angular CLI. My backend is tomcat, php with mysql on a hosting server to which I am able to successfully connect, get and update via post call all the other content in the app using httpclient module. I run CLI with proxy.
App is running at localhost:4200
Without Authorization Header, API calls succeeds and I get the proper response:
{"status":true,"resp":"Login Success."}
from my login.php file.
Login Service:
const headers = new HttpHeaders({
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Basic ' + btoa(email+':'+pwd) <---Including this line gives me error
});
When I add this line 'Authorization': 'Basic ' + btoa(email+':'+pwd), the API calls itself fails. It doesn't even show is it OPTIONS/POST in console.
It gives (failed) net::ERR_EMPTY_RESPONSE on some line in zone.js. Not sure if this angular issue.
Req Headers I see in console:
Provisional headers are shown
Accept: application/json, text/plain, */*
Authorization: Basic YXNkZjphc2Rm
Content-Type: application/x-www-form-urlencoded
Referer: http://localhost:4200/home
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.129 Safari/537.36
Below is the screenshot link.
enter image description here
/public-html/project/api/login.php:
header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json; charset=UTF-8");
header("Access-Control-Allow-Methods: POST");
header("Access-Control-Max-Age: 3600");
header ("Access-Control-Allow-Credentials: true");
header("Access-Control-Allow-Headers: Origin, Content-Type, X-Auth-Token, Access-Control-Allow-Headers, Authorization, X-Requested-With");
$json = file_get_contents('php://input');
$data = json_decode($json,true);
I've also tried most of the .htaccess solutions. Nothing worked.
.htaccess(in /public_html):
RewriteEngine On
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]
//Tried this too
RewriteEngine On
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
Header add Access-Control-Allow-Credentials true
Header add Access-Control-Allow-Methods "GET, POST, PUT, HEAD, OPTIONS, DELETE, PATCH"
Header add Access-Control-Allow-Headers *
Header always set Access-Control-Expose-Headers "*"
Header add Access-Control-Allow-Origin *
Header set Connection keep-alive
Header set Access-Control-Max-Age "3600"
Header set Access-Control-Allow-Headers "X-Requested-With, Content-Type, Origin, Authorization, Accept, Client-Security-Token"
The same request works in postman when I use Basic Auth, I am able to print the authorization header in php script as well. But it doesnt work in browser, any ideas why ?
Struck since 2 days. Can't get this to work.
I dont want to expose username/password in POST formData, but want to send it in Authorization header. How can I get this to work ? Should I add .htaccess somewhere in subfolders ?

Response to preflight request - can't see why? (CORS, fetch, PHP)

I found many discussions online about this, e.g. such as this great accepted answer, but still can't work out what's wrong. I've done the following:
Created a React app using create-react-app.
Started the server using npm start and can see my app in the browser.
Using fetch to contact my local server:
fetch("http://xxx.xxx.xxx.xxx/endpoint.php", {
method: "post",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
body: JSON.stringify({
name: credentials.username,
password: credentials.password
})
}).then(response => {
console.log("fetch competed!");
});
In my PHP endpoint,
<?php
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: X-Requested-With, Content-Type, Origin, Cache-Control, Pragma, Authorization, Accept, Accept-Encoding");
header("Access-Control-Allow-Methods: PUT, POST, GET, OPTIONS, DELETE");
...
But then Chrome console debug says:
Access to fetch at 'http://localhost:3000/endpoint.php' from origin 'http://xxx.xxx.xxx.xxx:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
Having done some reading, the preflight request sends an OPTIONS to the server, which I have allowed in the PHP header. I also tried some proxies in the package.json file and restarted the server using npm start.
I also tried passing through https://cors-anywhere.herokuapp.com/ and I still get an error:
Access to fetch at 'http://xxx.xxx.xxx.xxx:3000/php/login.php' (redirected from 'https://cors-anywhere.herokuapp.com/http://xxx.xxx.xxx.xxx:3000/php/login.php') from origin 'http://xxx.xxx.xxx.xxx:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
I also tried replacing my fetch with something simpler:
fetch(url, {
method: "POST",
body: new URLSearchParams("email=test#example.com&password=pw")
});
but still it does not work.
I don't understand what the problem could be?
For those facing similar problems, I managed to fix this issue by starting a separate Apache server, systemctl start apache, and hosting my PHP endpoints in the Apache root, e.g. /var/www/html/public/. For some reason the create-react-app development server just wouldn't work, but hosting my files on a separate local server worked fine.

Cross domain AJAX request failing

I'm trying to make a cross domain ajax request i have set the PHP headers on the receiving end and set the jQuery AJAX request but for some reason it works then you refresh the page and it fires a cors origin error with a response code of 503 which from my research its caused by CORS.
I have followed some instructions from here How do I send a cross-domain POST request via JavaScript?
Headers for api.mydomain.co.uk
header('Access-Control-Allow-Origin: https://mydomain.co.uk');
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS');
jQuery for mydomin.co.uk
$.ajax({
type: 'POST',
url: "//api.mydomain.co.uk/application/mp/basket",
crossDomain: true,
xhrFields:{withCredentials: true},
data: {Route: "ItemCount"},
success: function(data) {
$('.count').text(data);
}
});
Browser Response
It turns out that some Plesk installations are a bit buggy and the 503 error comes from the proxy_fcgi apache process.
To temporaraily fix this error you need to set your application in plesk to use FastCGI instead of FPM served by Apache/Nginx.
I once had this issue and I solved by this, I created an .htaccess file in the target website I was trying to access.
<IfModule mod_headers.c>
SetEnvIf Origin "http(s)?://(www\.)?(mydomain)$" AccessControlAllowOrigin=$0$1
Header add Access-Control-Allow-Origin *
</IfModule>
Its an IF condition if the domain which is requesting has mydomain in it then it will allow you to access.
The CORS policy should also specify which headers you can send.
The 503 is a little bit strange. I think you need to set Content-Type in the list of allowed headers, and maybe others. According to MDN these: https://developer.mozilla.org/en-US/docs/Glossary/simple_header are the headers that you don't need to explicitly send
header('Access-Control-Allow-Headers: Content-Type, etc');

Symfony 2.5 and Angular $http

I have some problem when I'm using $http with my API that I've written using Symfony. When I'm using $http.get at server side I'm adding a header to response : Access-Control-Allow-Origin and everything works and I can get required data from server. But when I'm using $http.post and adding this header , nothing works.
$http.post('http://myhost.loc/posts', {data:'Test string'}).success(function(data, status){
console.log(data);
}).error(function(data, status){
console.log(status);
});
And I get an error :
OPTIONS http://myhost.loc/posts and
No 'Access-Control-Allow-Origin' header is present on the requested resource.
I don't understand why this doesn't work.
its a CORS problem first of all enable CORS on your angular app by
myApp.config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
}
]);
A server supporting CORS must respond to requests with several access control headers:
• Access-Control-Allow-Origin *
Before sending a cross domain request, there is a preflight request sent with the OPTIONS method.
The purpose of that preflight request is to check if the ressource is reachable
You can try that in your apache .htaccess
<ifModule mod_headers.c>
Header always set Access-Control-Allow-Origin: "*"
Header always set Access-Control-Allow-Methods "POST, GET, PUT, DELETE, OPTIONS"
Header always set Access-Control-Allow-Headers "origin, x-requested-with, content-type"
</ifModule>

Categories