I finished my Angular project.
In my project I send POST requests with data to PHP files, and then get result from them back to Angular.
Now I want to allow requests only from the origin domain, and deny any request from any othe domain.
I try to use:
header("Access-Control-Allow-Origin: example.com");
but it does not work. And I don't want to use $_SERVER['HTTP_REFFER'] because it can manipulated.
I also tried to use .HTACCESS but I don't know how to implement that. I tried something like that:
order deny, allow
deny from all
allow from mydomain.com
but it does not work.
My project already has the following .HTACCESS file:
RewriteEngine On
# If an existing asset or directory is requested go to it as it is
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]
# If the requested resource doesn't exist, use index.html
RewriteRule ^ /index.html
taken from here: https://angular.io/guide/deployment#routed-apps-must-fallback-to-indexhtml
What can I do?
Thanks.
Short answer :
header("Access-Control-Allow-Origin: *");
Is the minimum that should work (on your server side), but you may need to add two additional headers like:
header("Access-Control-Allow-Methods: POST, GET, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type");
Like any header() call, be sure to perform those BEFORE any output.
Long answer:
CORS allow, with a relative security, to perform cross origin queries, depending on a pre-flight request OPTIONS to check what's allowed and what's not.
Access-Control-Allow-Origin sets which origins (domains) are allowed. You may want to use only your trusted domains.
Access-Control-Allow-Methods sets which methods are allowed. Usually, a lot of those.
Access-Control-Allow-Headers sets which optional (and customized) headers are allowed. Usually, you want to include any non-standard headers on top of Content-type.
CORS is incredibly well documented here : https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
I am running an angularjs application in my local system apache(http://localhost:8080). Here am trying to hit an API with post method. My API(http://php.mpect.com/demo/login.php) is hosted in godaddy server domain. Its a PHP file. I included
header('Access-Control-Allow-Origin: *');
in my php file, but still am getting
XMLHttpRequest cannot load http://php.mpect.com/demo/login.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:8080' is therefore not allowed access.
I am new to php and godaddy server. How can I solve this? Is there any way to include headers in godaddy domain? sorry for my english. Can anyone please provide me solution code to acheive this CORS problem. Thanks in advance.
Add the configuration into your .htaccess file and you will be fine. This will ensure that the important CORS headers will set on any request. Ensure you have enabled mod_headers on apache2.
# Always set these headers.
Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT"
Header always set Access-Control-Max-Age "1000"
Header always set Access-Control-Allow-Headers "x-requested-with, Content-Type, origin, authorization, accept, client-security-token"
I have an api with php implemented for login authenrication:
http://somerestsertver.net/sampleapi/auth-login this sets the login session id (e.g. after verifying user credentials)
http://somerestsertver.net/sampleapi/auth-check this checks the login is valid if the session id is set or not
http://somerestsertver.net/sampleapi/auth-logout and this destroys the session and needed logout ...
I set login with $_SESSION["id"]=1 when auth-login in the code
then auht-check would be ok, otherwise the auth-check would contain errors.
it is ok when I call these urls in browser or a ReST Client,
but using them in my angularJS code returns errors for http://somerestsertver.net/sampleapi/auth-check!
it seems the session set is not available via PHPSESSID in the client and it is not working properly
Is it related to sandbox or CORS or html header requests?
Hi I solved the problem finally this way:
Client side, in angularJS I put this in my route-config to apply for all request to ReST-API
$httpProvider.defaults.withCredentials = true;
I think I should have mainly use in .htaccess for web server:
Header add Access-Control-Allow-Credentials "true"
but for your attention, I updated finally the whole .htaccess file to the following:
Header add Access-Control-Allow-Origin "http://localhost:3000"
Header add Access-Control-Allow-Credentials "true"
Header add Access-Control-Allow-Headers "origin, x-requested-with, content-type"
Header add Access-Control-Allow-Methods "GET, POST"
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [QSA,L]
<FilesMatch "\.php$">
Order Allow,Deny
Deny from all
</FilesMatch>
<FilesMatch "index[0-9]?\.php$">
Order Allow,Deny
Allow from all
</FilesMatch>
also I use the following for JSON response in php:
$response="desired JSON response OBJECT";
$status='OK or unauthenticated or ...' ;
$status='200 or 403 or ...';
header("Content-Type:application/json");
header("HTTP/1.1 $status $status_message");
echo json_encode($response);
exit();
Hope this question and answer helps you
how can i solve Access-Control-Allow-Origin problem on Codeigniter? I've tried header('Access-Control-Allow-Origin: *'); etc. But no response still have the problem. Need help about this one. Regards.
My PHP codes: http://codepaste.net/r27eua
My JS codes: http://codepaste.net/ev35me
where do you write the header code? I thing you have to write it on page which will be opened by your request!
This might be an old question, but for sake of people who will bump in here like I did, this is how I solved my CORS puzzle.
If you use apache, make sure you have mod_headers enabled, this is enabled by default, but just to be sure, you can run sudo a2enmod headers in terminal.
Then on your .htaccess file, add the below code.
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept"
</IfModule>
Voila...
I have created a basic RESTful service with the SLIM PHP framework and now I'm trying to wire it up so that I can access the service from an Angular.js project. I have read that Angular supports CORS out of the box and all I needed to do was add this line: Header set Access-Control-Allow-Origin "*" to my .htaccess file.
I've done this and my REST application is still working (no 500 internal server error from a bad .htaccess) but when I try to test it from test-cors.org it is throwing an error.
Fired XHR event: loadstart
Fired XHR event: readystatechange
Fired XHR event: error
XHR status: 0
XHR status text:
Fired XHR event: loadend
My .htaccess file looks like this
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ /index.php [QSA,L]
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Methods: "GET,POST,OPTIONS,DELETE,PUT"
Is there something else I need to add to my .htaccess to get this to work properly or is there another way to enable CORS on my server?
Since I had everything being forwarded to index.php anyway I thought I would try setting the headers in PHP instead of the .htaccess file and it worked! YAY! Here's what I added to index.php for anyone else having this problem.
// Allow from any origin
if (isset($_SERVER['HTTP_ORIGIN'])) {
// should do a check here to match $_SERVER['HTTP_ORIGIN'] to a
// whitelist of safe domains
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, PUT, DELETE, OPTIONS");
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']))
header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");
}
credit goes to slashingweapon for his answer on this question
Because I'm using Slim I added this route so that OPTIONS requests get a HTTP 200 response
// return HTTP 200 for HTTP OPTIONS requests
$app->map('/:x+', function($x) {
http_response_code(200);
})->via('OPTIONS');
Should't the .htaccess use add instead of set?
Header add Access-Control-Allow-Origin "*"
Header add Access-Control-Allow-Methods: "GET,POST,OPTIONS,DELETE,PUT"
This is what worked for me:
Header add Access-Control-Allow-Origin "*"
Header add Access-Control-Allow-Headers "origin, x-requested-with, content-type"
Header add Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"
As in this answer Custom HTTP Header for a specific file you can use <File> to enable CORS for a single file with this code:
<Files "index.php">
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Methods: "GET,POST,OPTIONS,DELETE,PUT"
</Files>
Instead of "*" you can put specific origin (protocol + domain+ optional port).
Will be work 100%, Apply in .htaccess:
# Enable cross domain access control
SetEnvIf Origin "^http(s)?://(.+\.)?(1xyz\.com|2xyz\.com)$" REQUEST_ORIGIN=$0
Header always set Access-Control-Allow-Origin %{REQUEST_ORIGIN}e env=REQUEST_ORIGIN
Header always set Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
Header always set Access-Control-Allow-Headers "x-test-header, Origin, X-Requested-With, Content-Type, Accept"
# Force to request 200 for options
RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule .* / [R=200,L]
It's look like you are using an old version of slim(2.x). You can just add following lines to .htaccess and don't need to do anything in PHP scripts.
# Enable cross domain access control
SetEnvIf Origin "^http(s)?://(.+\.)?(domain_one\.com|domain_two\.net)$" REQUEST_ORIGIN=$0
Header always set Access-Control-Allow-Origin %{REQUEST_ORIGIN}e env=REQUEST_ORIGIN
Header always set Access-Control-Allow-Methods "GET, POST, PUT, DELETE"
Header always set Access-Control-Allow-Headers: Authorization
# Force to request 200 for options
RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule .* / [R=200,L]
Thanks to Devin, I figured out the solution for my SLIM application with multi domain access.
In htaccess:
SetEnvIf Origin "http(s)?://(www\.)?(allowed.domain.one|allowed.domain.two)$" AccessControlAllowOrigin=$0$1
Header set Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
Header set Access-Control-Allow-Credentials true
in index.php
// 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, PUT, DELETE, OPTIONS");
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']))
header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");
}
// instead of mapping:
$app->options('/(:x+)', function() use ($app) {
//...return correct headers...
$app->response->setStatus(200);
});
For ubuntu users:
You have to activate first the headers module by using the following command:
sudo a2enmod headers
Then restart apache by:
sudo service apache2 restart
Then add the following headers to your htaccess:
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Headers "origin, x-requested-with, content-type"
Header set Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"
I tried #abimelex solution, but in Slim 3.0, mapping the OPTIONS requests goes like:
$app = new \Slim\App();
$app->options('/books/{id}', function ($request, $response, $args) {
// Return response headers
});
https://www.slimframework.com/docs/objects/router.html#options-route