CORS and HTTP authentication - javascript

I'm trying make some ajax queries from domain A to domain B which is behind HTTP basic auth
Here is my Jquery (1.9.1) ajax call
jQuery.ajax({
method : "POST",
data: s,
withCredentials: true,
headers: {
"Authorization" : "Basic " + btoa('user:pass')
},
url: "http://domainB/script.php",
success: function(data){
console.log(data);
}
});
And script.php
<?php
header('Access-Control-Allow-Origin: http://domainA');
header('Access-Control-Allow-Methods: POST');
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Allow-Headers: Authorization, Content-Type');
header('Content-Type: application/json');
/**
* Some stuff here
*/
echo json_encode( $json_response );
For some reason I ignore, I got this error in javascript console
Access to XMLHttpRequest at 'http://domainB/script.php' from origin 'http://domainA' 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
I don't understand what the error is, Access-Control-Allow-Origin is set...
I tried many solutions found a little bit everywhere but without success.. May someone have a solution ?
Thanks

Related

JS fetch + php codeigniter4 CORS issue

I'm using vue3 with codeigniter4 .I am getting a CORS issue with fetch When sending a custom header even I set what should be set for CORS in server side method (Without using the framework filters ,Just pure php)
my js code is :
GetMyOrders() {
fetch(this.AppMainData.ApiUrl+'orders/get', {
method: 'GET',
headers:{
'Role': 'some role',
}
}).then(response => response.json())
.then(data => {
console.log(data);
this.MyOrders = data.result;
this.explode;
return;
})
}
And my php code in codeigniter controller (Not resource) is :
public function GetMyOrders(){
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Role ,Content-Type,Origin');
header('Access-Control-Allow-Credentials:true');
$db=\Config\Database::connect();
$data['result']=$db->query("Some SQL Query")->getResult();
return json_encode($data);
}
The fetch is successful when not fetching with header , but when i add my custom header the response is blocked by CORS policy as bellow:
"Access to fetch at 'http://localhost/MyApp/public/api/orders/get' from origin 'http://localhost:8080' 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."
Any idea please (Without using External Solutions) !!!
It's solved .As the Bros mentioned in replies (A preflight request issue)
Just adding this checking Request Code in (Routes.php) And The problem is solved
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']) &&
$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'] == 'GET') {
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Headers:Role,Origin , Content-Type');
}
exit;
}
Thank U Guys

Post request works in postman but not in javascript fetch function

I thought I had solved this issue before and was able to make succesful post request to my local hosted apache server with fetch, but today I tried to make a post and I've gotten 'cors preflight request fail' error again. I'm not sure why it was working before and why it's suddenly not working again.
this is my php file headers which worked 3 days ago -
header('Access-Control-Allow-Origin: *');
header('Content-Type: application/json');
header('Access-Control-Allow-Methods: POST, OPTIONS');
header('Access-Control-Allow-Headers: Access-Control-Allow-Headers,Content-Type,Access-Control-Allow-Methods,
Authorization, X-Requested-With');
and this is the fetch request I'm using on it -
fetch("http://menu.com/menu/api/post/create.php", {
method: "POST",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
'title' : 'qweqweqw',
'body' : '1111w',
'author' : '2222r',
'category_id' : '2'
})
})
.then( (response) => {
console.log(response);
});
here is the Postman code that is working :
POST /menu/api/post/create.php HTTP/1.1
Host: menu.com
Content-Type: application/json
cache-control: no-cache
Postman-Token: 83a8e0d1-f45a-4184-92f6-f0be2f8fcf5f
{
"title" : "new new title",
"body" : "new neqwsadasssssssssseqweqwew jew",
"author" : "new newzxxxxxxxxxxxxwq author",
"category_id" : "1"
}------WebKitFormBoundary7MA4YWxkTrZu0gW--
I'd appreciate any help with this.
edit-
These are the cors errors :
Access to fetch at 'http://menu.com/menu/api/post/create.php' from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
In my apache server error log I get this ' PHP Fatal error: Uncaught PDOException: SQLSTATE[HY000]: General error: 1366 Incorrect integer value: '' for column 'category_id' at row 1 in /home/orphe$' But I'm not sure why it's getting this for category_id since I copy/pasted the working request from postman and it still doesn't work.
There's a preflight request (with OPTIONS), but the server doesn't return HTTP 200 OK.
Try adding the following to create.php:
header("HTTP/1.1 200 OK");
If this doesn't work please also include the request and response headers.
Changing my fetch requests headers to headers: new Headers() fixed everything.

CORS-issue - "No 'Access-Control-Allow-Origin' header is present on the requested resource."

So I've been trying to pass data from my front-end to my back-end (however, I'm not very experienced within this area). The data comes through, however, if I try to insert the data into my MySQL-DB through PDO the browser gives me the following error:
Failed to load http://localhost:8888/post_recipe.php: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled."
JS
postToAPI = () => {
fetch(`http://localhost:8888/post_recipe.php`, {
method: 'POST',
headers: {
'Content-Type': 'text/html'
},
mode: 'cors',
body: JSON.stringify({
title: this.state.title,
description: this.state.description,
userID: this.props.userInfo.response.id,
name: this.props.userInfo.response.name,
stepByStep: (this.state.stepByStep),
recipeIngredients: (this.state.recipeIngredients),
profileImg: this.props.userInfo.response.picture.data.url
})
})
.then((response) => response.json())
.then((fetch) => {
console.log(fetch)
});
}
PHP
<?php
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Credentials: true');
header("Content-type: text/html; charset=utf-8");
header('Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Origin, Content-Type, X-Auth-Token');
$post = json_decode(file_get_contents('php://input'));
$array = json_decode(json_encode($post), True);
$pdo = new PDO(
"mysql:host=localhost:8889;dbname=veganify;charset=utf8",
"root",
"root"
);
$statement = $pdo->prepare(
"INSERT INTO posts (title, description, userID, name, stepByStep, recipeIngredients, profileImg)
VALUES (:title, :description, :userID, :name, :stepByStep, :recipeIngredients, :profileImg)"
);
$statement->execute(array(
":title" => $array["title"],
":description" => $array["description"],
":userID" => $array["userID"],
":name" => $array["name"],
":stepByStep" => $array["stepByStep"],
":recipeIngredients" => $array["recipeIngredients"],
":profileImg" => $array["profileImg"]
));
}
echo json_encode($array);
?>
So if I delete the MySQL-insertion, the data comes back to the front-end. I have been stuck here for a while now searching various forums for a solution. The error message says that the header is not present, however it is there, as you can see.
Any help would be much appreciated!
Cheers!
Good afternoon, this is because of the apache blocking requests from different sources ie if your backend is at http://yourdomain.com/client and your font-end is at localhost:3001 will cause a because they are of different (host) origins.
To solve:
Use the .htaccess file in your api / backend folder, for example, in my application my index.php is not in localhost / my-api / public directory then my .htaccess file in this directory directory localhost / my-api / public
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Origin: "*" (allow access from any origin)
Header set Access-Control-Allow-Origin: "http://motech-ui.example" (allow access from only "http://motech-ui.example" origin)
Access-Control-Allow-Origin: "http://motech-ui.example | http://other.domain" (allow access from two mentioned origins)
</IfModule>
Or config in apache.conf
Access-Control-Allow-Origin: "*" (allow access from any origin)
Access-Control-Allow-Origin: "http://motech-ui.example" (allow access from only "http://motech-ui.example" origin)
Access-Control-Allow-Origin: "http://motech-ui.example | http://other.domain" (allow access from two mentioned origins)
CORS in Javascript and PHP works like.
OPTIONS method request will be triggered from browser side.
Server side (PHP) should accept the OPTIONS request, by responding 'OK'.
Now a proper POST request will be triggered from browser side, which will go to your functionality location where your PHP code will gets executed.
if ($_SERVER["REQUEST_METHOD"] === "OPTIONS") {
//location where you can handle your request and respond ok
echo 'OK';
}
If you can not control the sever side, you can work around like me on
Client side only.
If you can control server side, you can use server side solution. I am not discus it here.
Only on client side, work around is
use dataType: 'jsonp',
async function get_ajax_data(){
var _reprojected_lat_lng = await $.ajax({
type: 'GET',
dataType: 'jsonp',
data: {},
url: _reprojection_url,
error: function (jqXHR, textStatus, errorThrown) {
console.log(jqXHR)
},
success: function (data) {
console.log(data);
// note: data is already json type, you just specify dataType: jsonp
return data;
}
});
} // function

Posting data to different domain using PHP, AJAX don't work

I'd like to post data from domain1.com to domain2.com using AJAX, but my request fails.
Here's is my code on domain1.com:
$.ajax({
type: 'POST',
url: 'https://domain2.com/payment/api/server',
crossDomain: true,
data: {
Name: $("#name").val().trim(),
Email: $("#email").val().trim()
},
dataType: 'json',
success: function(data) {
alert('Success');
},
error: function (data) {
alert('POST failed.');
}
});
and here's my server side code on domain2.com:
switch ($_SERVER['HTTP_ORIGIN']) {
case 'http://domain1.com/api/': case 'http://domain1.com/api/':
header('Access-Control-Allow-Origin: '.$_SERVER['HTTP_ORIGIN']);
header('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS');
header('Access-Control-Max-Age: 1000');
header('Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With');
break;
}
$name = $_POST['Name'];
echo $name; // Just to check if I receive the value from index.php
You are checking if Origin HTTP header equals to 'http://domain1.com/api/'. However, MDN CORS docs say:
The origin is a URI indicating the server from which the request initiated. It does not include any path information, but only the server name.
You have to remove the path from the string, i.e. it has to be 'http://domain1.com'.
Corrected server.php code:
switch ($_SERVER['HTTP_ORIGIN']) {
case 'http://domain1.com':
header('Access-Control-Allow-Origin: '.$_SERVER['HTTP_ORIGIN']);
header('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS');
header('Access-Control-Max-Age: 1000');
header('Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With');
break;
}
$name = $_POST['Name'];
echo $name;
As a side note: if you are using the "HTTP_ORIGIN" header to "secure" your requests, you should rethink it. Anyone can spoof this header and arbitrarily set the value. You are better off using some kind of key/secret to avoid unwanted requests. See: Is CORS a secure way to do cross-domain AJAX requests?

CORS is not working with ionic

I am trying to send a json to a php script on a server and even though I have included header in php script to have CORS the console throws error
error message
XMLHttpRequest cannot load http://www.awesomegag.0fees.us/updata.php. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8100' is therefore not allowed access. The response had HTTP status code 403.
my code :
php
<?php
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST');
header("Content-Type: application/json; charset=UTF-8");
if (isset($_SERVER['HTTP_ORIGIN'])) {
header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Max-Age: 86400'); // cache for 1 day
}
// Access-Control headers are received during OPTIONS requests
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']))
header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']))
header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");
exit(0);
}
echo"hello";
$postdata = file_get_contents("php://input");
$request = json_decode($postdata);
?>
My app.js
.controller('datactr', ['$scope','$http','ApiEndpoint',function($scope,$http,ApiEndpoint) {
$scope.submit=function(){
console.log("step1");
$http({
method:'POST',
url:'http://www.awesomegag.0fees.us/updata.php',
data:{
'name':$scope.name
}
}).success(function(data,status,header,config){
console.log("step2");
console.log(data);
})
});
I tried to make it work using proxy method by making path /api and proxyUrl to updata.php address in ionic.project and then replace url in http service to /api. I get a 500 internal server error.
Can anyone help ?
Update: I have moved to a different server where everything works fine.I guess it is some problem with the server but have no idea how to fix it.
Looks like that your server doesn't allow OPTIONS method.
Modern browser do "pre-flight" request for cross origin request to make sure that it is allowed to do so before sending GET/POST request.
Solution: Enable OPTIONS command. Example for Apache http://httpd.apache.org/docs/trunk/mod/mod_allowmethods.html

Categories