I'm currently working on a PHP REST API for a uni project, which uses JSON web tokens passed from mobile web applications using PhoneGap, or my desktop during development.
When sending the token to my server page "friends/read.php" using ajax, the server was picking up the Authorization header correctly with
$headers = getallheaders();
$authHeader = $headers['Authorization'];
but stopped doing so after several successful runs. After that point, the header is no longer being picked up.
My request code is as follows:
$.ajax({
url: "http://localhost/chordstruck/api/friends/read.php",
type: "GET",
beforeSend: function (request) {
request.setRequestHeader('Authorization', 'Bearer ' + localStorage.getItem('jwt'));
},
datatype: "json",
success: function (response) {
console.log(response);
},
error: function (jqXHR, textStatus, errorThrown) {
console.log(jqXHR);
}
});
Oddly enough, when killing the PHP script prematurely with die("test") and then removing die() again, the server will then start picking up the Authorization header for several more requests.
Read.php:
<?php
error_reporting(E_ALL);
ini_set('display_errors', 'on');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET');
header('Access-Control-Allow-Headers: Origin, Content-Type, Authorization, X-Auth-Token');
$config = require_once '../config/core.php';
require_once '../config/jwt_helper.php';
// get database connection
include_once '../config/database.php';
// instantiate profile object
include_once '../objects/profile.php';
$headers = getallheaders();
$authHeader = $headers['Authorization'];
$token;
if ($authHeader) {
list($jwt) = sscanf((string)$authHeader, 'Bearer %s');
if ($jwt) {
try {
$key = $config['jwt_key'];
$token = JWT::decode($jwt, $key, array('HS512'));
} catch (Exception $e) {
header('HTTP/1.0 401 Unauthorized');
exit();
}
} else {
header('HTTP/1.0 400 Bad Request');
exit();
}
} else {
header('HTTP/1.0 400 No Header Found');
exit();
}
echo "success";
?>
I have been encountering a CORS issue while developing this project, which I've countered with the above headers along with the following in my .htaccess file:
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "*"
</IfModule>
Could this potentially be related? Any help/ideas would be greatly appreciated!
The problem appears to have been indeed related to CORS and after trying a multitude of approaches, the following solution is now working.
Replacing my headers in read.php with:
// Allow from any origin
if (isset($_SERVER['HTTP_ORIGIN'])) {
// Decide if the origin in $_SERVER['HTTP_ORIGIN'] is one
// you want to allow, and if so:
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']))
// may also be using PUT, PATCH, HEAD etc
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);
}
Credit goes to slashingweapon who used it to answer CORS with php headers
Related
I have problem with request POST in fetch function. I make REST API with react and PHP and I get error Access-Control-Allow-Origin is required. I have this header in my web api. This is my code (begin) in PHP:
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: GET,POST,PUT,DELETE");
header("Access-Control-Expose-Headers: access-control-allow-origin");
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
header("Content-Type: application/json; charset=UTF-8");
and in React:
//method = POST
//body = {"name":"test","body":"test"}
const apiCall = (url, method, body, resolve, reject) => {
fetch(url, {
method: method,
headers: {
'Content-Type': 'application/json; charset=utf-8'
},
body: JSON.stringify(body)
}).then(resp => {
if(resp.ok) {
resp.json().then(json => resolve(json));
}
else {
reject(resp);
}
});
}
I try to communicate with other server and api - result was the same.
Screen with error in Google Chrome browser:
screen
Please help.
You have to add the CORS MODULE and Proxy in Server.
Facing CORS in angular, when i was trying to make a API call between my localhost to another domain.I am getting 404 issue .
1.Front End : Angualr 7
Front end request part:
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Credentials': 'true',
'Access-Control-Allow-Methods':'POST',
'Access-Control-Allow-Headers': 'Content-Type'
})
}
login(username: string, password: string) {
return this.http.post<any>('http://remote/djaxtesting/enter_uiupgrade/index.php/api/v1/user/validate',
{acc_type: "ADMIN", uemail: "djax_admin#dreamajax.com", upw: "123456"},httpOptions)
.pipe(map(user => {}))
}
Back end coding :
<?php defined('BASEPATH') OR exit('No direct script access allowed');
header ("Access-Control-Allow-Origin: *");
header ("Access-Control-Allow-Credentials: true");
header('Access-Control-Allow-Methods: POST');
header('Access-Control-Allow-Headers: Content-Type');
header('Content-Type: application/json');
public function validate_post()
{
$role = array('ADVERTISER','TRAFFICKER','ADMIN','MANAGER');
if($this->post('acc_type') !='' and in_array($this->post('acc_type'),$role))
{
switch(strtoupper($this->post('acc_type')))
{
case "ADMIN":
$adminObj = $this->do_networks->validate_user($this->post('uemail'),$this->post('upw'),$this->post('acc_type'));
//$this->response($adminObj, 200);
}
}
}
enter image description here
We using php for api. Helping handing needs to solve this issue ?
The problem with the option method. Option request should be a 200 returning an empty response. Then the browser will send the real POST request.
for that replace with the headers in your PHP File in the constructor. It will work.
header('Access-Control-Allow-Origin: *');
header("Access-Control-Allow-Headers: X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Request-Method, Authorization");
header("Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE");
$method = $_SERVER['REQUEST_METHOD'];
if ($method == "OPTIONS") {
die();
}
I'm creating an angular application 6 and api rest in php.
when my angular application tries to perform a request the following url: http://localhost/bdevApi/api/index/categoryexame?page=1
the following error is loaded:
Failed to load 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:4200' is therefore
not allowed access.
The angle is in port 4200 and my api is in 80
I visualized some tutorial and added the following header to my api
api/index.php
<?php
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Origin, Content-Type, X-Auth-Token');
include("config/config.php");
include("import/Interpreter.php");
include("import/SendJson.php");
include("database/Connection.php");
include("import/AuthToken.php");
$db = Connection::getInstance();
if( $db->getStateConnection() )
{
$arrayHeader = getallheaders();
$token = isset($arrayHeader["token"]) ? $arrayHeader["token"] : "";
// Recupera dados via Json
$strJson = file_get_contents('php://input'); //echo $strJson;
$jsonObject = json_decode($strJson); //var_dump($strJson);
$Interpreter = new Interpreter(
"http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]",
$_SERVER['REQUEST_METHOD'],
$jsonObject
);
if(AuthToken::validateToken($token))
$Interpreter->initializes(true);
else
{
if($token == "")
$Interpreter->initializes(false);
else
{
$S = new SendJson();
$S->Send("200", "1", "Token não autenticado", null);
}
}
$db->closeConnection();
}
?>
How do I get my application to accept these headers and not show this error?
[EDIT]
[]1
new error
Failed to load
http://localhost/bdevApi/api/index/categoriaexame?page=1: No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:4200' is therefore not allowed
access.
This is happening because of cross origin policy. You can go through this document to get the details knowledge about CORS:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Server-Side_Access_Control
You can try this code below:
// Allow from any origin
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);
}
I'm trying to do a simple POST from angularjs to a dummy php file to understand how this works.
Here in my angularjs part:
<html ng-app="loginApp">
<head>
<meta charset="utf-8">
<title>Login</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
<script>
var logindata = {username:'abc', password:'abc'}
var loginApp = angular.module('loginApp', []);
loginApp.controller('loginCtrl', function ($scope, $http){
var request = $http({
method: "POST",
url: "http://different-ip/a.php",
data: logindata,
headers: { 'Content-Type': 'multipart/form-data', 'Authorization': 'Basic ' + btoa(logindata.username + logindata.password),
'Access-Control-Allow-Origin': "*"}
});
request.success(
function( data ) {
$scope.someVariableName = data;
}
);
});
</script>
</head>
<body ng-controller="loginCtrl">
<h2>Angular.js JSON Fetching Example</h2>
<p> {{ someVariableName }} </p>
</body>
</html>
Here is my PHP part (a.php) that resides on http://different-ip
<?php
header("Access-Control-Request-Method: *");
header("Access-Control-Request-Headers: *");
header("Access-Control-Allow-Origin: *");
file_put_contents("aa.txt", json_decode(file_get_contents('php://input'),true));
file_put_contents("aaa.txt", getallheaders());
?>
When I execute my angularjs file, the chrome console gives me this error:
Request header field Access-Control-Allow-Origin is not allowed by Access-Control-Allow-Headers in preflight response.
When I try doing a post to this a.php using Postman, everything works fine. So why is angularjs not allowing it?
I've tried to read about CORS and there is no straightforward answer to how this issue can be resolved (code wise). Can someone please help me out? Thanks in advance.
Added this instead of current headers to my PHP file and now it works! Thanks #Armen for your help!
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);
}
Add this 3 headers at top of a.php instead current ones with if condition
<?php
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS");
header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization");
if($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
header( "HTTP/1.1 200 OK" );
exit;
}
file_put_contents("aa.txt", json_decode(file_get_contents('php://input'),true));
file_put_contents("aaa.txt", getallheaders());
?>
You can check more about CORS here: http://www.w3.org/TR/cors/#access-control-allow-headers-response-header
Postman works because it is additional browser extension which don't cares about headers policy and don't check it before request.
I would like to realize an Google Chrome extension, which would show a notification following the result of an Ajax request.
I coded the function which allows to create a notification, so I just have to do the Ajax request which fetches a .php file on a remote server which belongs to me. This request just failed, nothing happened. Nevertheless when I try to realize the request since my server towards my server (without the extension), no problem, I deducted from it that it was a problem of "Cross-Domain"...
Here are the important elements (for the problem) of the manifest.json (I just put all possible permissions^^) :
{
"background": {
"scripts": ["myScript.js", "jquery-2.1.4.min.js"]
},
"manifest_version": 2,
"permissions": [ "http://*/", "https://*/" , "http://*/*" , "https://*/*", "tabs", "notifications", "browsingData", "webRequest", "webNavigation" ],
...
...
}
Here is the AJax request in myScript.js :
(The spawnNotification function works perfectly, tested without the request)
$.ajax({
url: "http://www.domain.com/test/get.php",
type: "GET",
crossDomain : true,
success: function() {
spawnNotification("Title", "work", "img/notif.png", "http://www.domain.cor/forum/");
},
error: function() {
spawnNotification("Title", "error", "img/notif.png", "http://www.domain.co/forum/");
}
});
And finally, the get.php file :
<?php
header("Content-Type: text/plain");
header("Access-Control-Allow-Origin: *");
$str = 15;
echo $str;
?>
What am I doing wrong here? Thanks !
( Here are some topics that did not help me...
Chrome extension Cross Domain Request
Chrome extension xhr cross domain request gives error:"is not allowed by Access-Control-Allow-Origin." )
You need to provide more response headers than just that one, see the Cross-Origin Resource Sharing specification for details.
Here's pseudo-code (from my other answer here) of what's required in your server code (sorry, don't write much PHP, hence pseudo-code):
// Find out what the request is asking for
corsOrigin = get_request_header("Origin")
corsMethod = get_request_header("Access-Control-Request-Method")
corsHeaders = get_request_header("Access-Control-Request-Headers")
if corsOrigin is null or "null" {
// Requests from a `file://` path seem to come through without an
// origin or with "null" (literally) as the origin.
// In my case, for testing, I wanted to allow those and so I output
// "*", but you may want to go another way.
corsOrigin = "*"
}
// Decide whether to accept that request with those headers
// If so:
// Respond with headers saying what's allowed (here we're just echoing what they
// asked for, except we may be using "*" [all] instead of the actual origin for
// the "Access-Control-Allow-Origin" one)
set_response_header("Access-Control-Allow-Origin", corsOrigin)
set_response_header("Access-Control-Allow-Methods", corsMethod)
set_response_header("Access-Control-Allow-Headers", corsHeaders)
if the HTTP request method is "OPTIONS" {
// Done, no body in response to OPTIONS
stop
}
// Process the GET or POST here; output the body of the response
#T.J. Crowder
Thanks Crowder, I tried to write it in PHP and I first tried that for my get.php :
<?php
header("Content-Type: text/plain");
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST');
header("Access-Control-Allow-Headers: X-Requested-With");
$str = 15;
echo $str;
?>
It doesn't work so I searched a bit with what you said, and found that https://stackoverflow.com/a/9866124/5733765
get.php :
<?php
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');
}
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);
}
$str = 15;
echo $str;
?>
But still doesn't work
I found the problem... we have to use xhr
myScript.js :
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://domain.com/test/get.php", true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
alert(xhr.responseText);
}
}
xhr.send();
Thanks for your help ;)
EDIT: the real problem was to define jquery.js after in the myScript.js
manifest.json:
"background": {
"scripts": ["jquery-2.1.4.min.js", "notification.js"]
},