Symfony Ajax same origin policy - ajax

I am trying to send an AJAX request from the domain: 127.0.0.1:8000 to localhost:8000. This call is ending in an
Status Code: 405 Method Not Allowed
I have add an listener, which is sending the right headers for the origin problem:
<?php
namespace AppBundle\Listener;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
/**
* Class CorsListener is handling on Kernel response header actions
* #package AppBundle\Listener
*/
class CorsListener {
public function onKernelResponse(FilterResponseEvent $event) {
$request = $event->getRequest();
// allow this only for the tracking URL
/*if(strpos($request->getHost(), 'api.') === false) {
return;
}*/
$event->getResponse()->headers->set('Access-Control-Allow-Headers', 'origin, content-type, accept');
$event->getResponse()->headers->set('Access-Control-Allow-Origin', '*');
$event->getResponse()->headers->set('Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE OPTIONS');
}
}
But even the headers, you can see in the image below, it is not possible to become the request.
Some help?

You seem to be missing a comma
$event->getResponse()->headers->set('Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE OPTIONS');
Should be
$event->getResponse()->headers->set('Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE, OPTIONS');
DELETE and OPTIONS are two separate methods.

I had to allow the OPTIONS method in my Symfony Controller:
* #Method({"GET", "POST", "OPTIONS"})

Related

Laravel api CORS error when posting from js

I have made an API with Laravel and I am getting an error when I am trying to make a post. I don't know if I need to send the crsf from javascript or if I have made the cors middleware wrong.
When I make a get to the API I don't have any cors issue.
This is my middleware. It has been added on the kernel.php file.
class Cors{
public function handle($request, Closure $next) {
return $next($request)
->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, Authorization, X-Requested-With, x-xsrf-token, ip');
}
}
On javascritp I have added this: 'Content-Type': 'application/json' on the header.
And this is the error that it's giving to me
Access to XMLHttpRequest at 'http://localhost:8000/api/user/1/videos/1/newComment' from origin 'http://localhost:4200' 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.
Thanks you a lot for your help.
Try adding this to the top of the index.php in the root of your project...
<?php
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS');
?>

Method PUT is not allowed by Access-Control-Allow-Methods in preflight response vue-laravel App

I am new in vue. For ajax request I am using axios and for back-end I am using Laravel. Whenever I send a POST and GET request it's works fine. But while trying to send a PUT Request its showing Method PUT is not allowed by Access-Control-Allow-Methods in preflight response vue-laravel App. I had read lots of answer in Stackoverflow and github but none of them worked for me.
Here is the client side code:
axios.put('http://127.0.0.1:8000/api/photo/6', this.photo, { headers: getHeader() })
.then(response => {
console.log(response.data.message);
}).catch(err => {
this.errors = err.response.data.errors;
});
Here is CROSS middleware code:
//allowed client
//now only for localhost vue cli
$domains = ['http://localhost:8080'];
if(isset($request->server()['HTTP_ORIGIN'])){
$origin = $request->server()['HTTP_ORIGIN'];
if(in_array($origin, $domains)){
header('Access-Control-Allow-Origin: '.$origin);
header('Access-Control-Allow-Headers: Origin, Content-Type, Authorization');
}
}
return $next($request);
Try this in backend :
app/Http/Middleware/Cors.php
public function handle($request, Closure $next)
{
return $next($request)
->header('Access-Control-Allow-Origin', '*')
->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE,
OPTIONS');
}
app/Http/Kernel.php $routedMiddleware array add
'cors' => \App\Http\Middleware\Cors::class,
Route/api.php
Route::group(['middleware' => 'cors'], function () {
Route::put('/v1/employees', 'Employees#store');
});
Particular GET, HEAD and POST HTTP requests do not trigger the CORS preflight OPTIONS check. They are called Simple Requests. They only send a subset of HTTP headers along. Any other additional header, like an Authorization header (think JWT authentication), will trigger a preflight OPTIONS request. The details on this can be found on https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
I think the easiest way for you to work with this, is to use the laravel-cors package on the backend (see https://github.com/barryvdh/laravel-cors).
While doing development, you can simply be very permissive by setting allowedOrigins, allowedHeaders and allowedMethods to *. Later on, during testing and subsequently production, you should tune it to be more strict. By that time you'll have a much better hang of CORS concepts, and then you can configure it fully to your needs.

POST Request to other server

I want to send a POST request to an other server with Ajax when a button is pressed.
But I'm getting the error message:
XMLHttpRequest cannot load https://www.example.com/hello. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://my.site.com' is therefore not allowed access.
This is my button:
<button id="my-button">Click me pls</button>
And this is the JS code:
document.getElementById("my-button").addEventListener("click", function (evt) {
var request = new XMLHttpRequest();
request.open('POST', 'https://www.example.com/hello', true);
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
request.setRequestHeader('X-CSRF-TOKEN', "<...>");
request.onreadystatechange = function () {
if (request.readyState == 4 && request.status == 200) {
console.log(request.responseText);
}
};
request.send("message=Thisismymessage&" +
"_token=<...>");
evt.preventDefault();
return false;
});
/hello should process and store the message in the database.
On the server side I'm using Laravel 5.4.
This is my route:
Route::post('/hello', 'Auth\RegisterController#hello')
->middleware('cors');
The cors Middleware looks like this:
namespace App\Http\Middleware;
use Closure;
class Cors
{
public function handle($request, Closure $next)
{
return $next($request)
->header('Access-Control-Allow-Origin', 'https//my.site.com')
->header('Access-Control-Allow-Methods', 'GET,HEAD,POST,PUT,PATCH,DELETE,OPTIONS')
->header('Access-Control-Allow-Headers', 'origin, content-type, accept, authorization');
}
}
The hello method in the RegisterController just takes the data (in this case the message "Thisismymessage") and puts it in the database.
protected function hello(Request $request)
{
// Working with the data...
}
Do any of you have an idea how to fix it?
And my additional question ist: is there a way to "generate" the CSRF token from Laravel from an other application which doesn't use Laravel as framework or do I have to copy & paste it manually?
Thank you in advance.
I could recommend a little hack to solve the second question, i.e:
is there a way to "generate" the CSRF token from Laravel from an other application which doesn't use Laravel as framework or do I have to copy & paste it manually?
Create an end point in the backend of your app to generate a view of the form. You should already include the csrf_token field when making this form, so that at your front end you have a complete form which you will submit again.
This look like a snake long way.
The more recommended way is that: it appears you are building an api, this makes it easy because its stateless. Use an api key example with JWT-AUTH, so that you don't have to deal any thing with csrf token.
For the first question:
You should just sort out the cors issue from your backend a good one is Cors middleware for Laravel 5
Others: Not recommended but for test purpose you can add these in the constructor of your controller to see how your app fair:
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE');
header('Access-Control-Allow-Headers: Content-Type, Accept, Authorization, X-Requested-With, Application');
Remember: This is useful only if you are doing a test.

Vuejs and Laravel Post Request CORS

I dont get it. I am struggling with this since hours
I am using Vue.js with Laravel and try to make a POST Request to an external API.
But i am always getting a CORS error on my Vue POST Request
methods: {
chargeCustomer(){
this.$http.post('/api/chargeCustomer', this.payment).then(function (response) {
console.log(response.data)
},function (response) {
console.log(response.data)
});
}
}
ERROR
MLHttpRequest cannot load
https://www.mollie.com/payscreen/select-method/JucpqJQses. No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'https://payment.dev' is therefore not allowed
access.
I installed the Laravel CORS Package for my Backend and added the middleware to my route e.g
Route::group(['middleware' => 'cors'], function(){
Route::post('/api/chargeCustomer', 'Backend\PaymentController#chargeCustomer');
});
But i am still getting the error. I also tried to add the Vue Headers with
Vue.http.headers.common['Access-Control-Allow-Origin'] = '*';
Vue.http.headers.common['Access-Control-Request-Method'] = '*';
With the same result/error.
Could someone tell me what i am doing wrong?
You need to set up the CORS headers from the middleware. Maybe you need some extra setup?
Anyway, you can create your own middleware and set up the CORS headers in the handle() method like the following example:
public function handle($request, Closure $next)
{
return $next($request)
->header('Access-Control-Allow-Origin', 'http://yourfrontenddomain.com') // maybe put this into the .env file so you can change the URL in production.
->header('Access-Control-Allow-Methods', '*') // or specify `'GET, POST, PUT, DELETE'` etc as the second parameter if you want to restrict the methods that are allowed.
->header('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type, Authorization') // or add your headers.
}
Add your custom middleware to the global $middleware array (under CheckForMaintenanceMode::class) in the Kernel.php class and you should be good to go.
Other way (without creating a new laravel middleware) is add these headers at the begining of your routes.php
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE');
header('Access-Control-Allow-Headers: Content-Type, X-Auth-Token, Origin, Authorization');
and add this before your interceptors on vue:
Vue.http.options.crossOrigin = true

HTTP OPTIONS error in Phil Sturgeon's Codeigniter Restserver and Backbone.js

My backbone.js application throwing an HTTP OPTIONS not found error when I try to save a model to my restful web service that's located on another host/URL.
Based on my research, I gathered from this post that :
a request would constantly send an OPTIONS http request header, and not trigger the POST request at all.
Apparently CORS with requests that will "cause side-effects on user data" will make your browser "preflight" the request with the OPTIONS request header to check for approval, before actually sending your intended HTTP request method.
I tried to get around this by:
Settting emulateHTTP in Backbone to true.
Backbone.emulateHTTP = true;
I also allowed allowed all CORS and CSRF options in the header.
header('Access-Control-Allow-Origin: *');
header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept");
header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
The application crashed when the Backbone.emulateHTTP line of code was introduced.
Is there a way to respond to OPTIONS request in CodeIgniter RESTServer and are there any other alternatives to allow either disable this request from talking place?
I found this on Github as one solution. I am not sure if I should use it as it seems a bit outdated.
I encountered exactly the same problem. To solve it I have a MY_REST_Controller.php in core and all my REST API controllers use it as a base class. I simply added a constructor like this to handle OPTIONS requests.
function __construct() {
header('Access-Control-Allow-Origin: *');
header("Access-Control-Allow-Headers: X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Request-Method");
header("Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE");
$method = $_SERVER['REQUEST_METHOD'];
if($method == "OPTIONS") {
die();
}
parent::__construct();
}
This just checks if the request type is OPTIONS and if so just dies out which return a code 200 for the request.
You can also modify the $allowed_http_methods property in your subclass to exclude the options method. Previous versions of REST_controller did nothing with OPTIONS and adding this line seems to mimic that behavior:
protected $allowed_http_methods = array('get', 'delete', 'post', 'put');
I solved in this way:
header('Access-Control-Allow-Origin: *');
header("Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE");
header("Access-Control-Allow-Headers: X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Request-Method, x_requested_with");
if ( "OPTIONS" === $_SERVER['REQUEST_METHOD'] ) {
die();
}
Pay attention to add x_requested_with in Access-Control-Allow-Headers.

Resources