Let's say I have a next js application which exists in a different domain that needs to call a laravel route. This route leads to a login page.
This is what I did on react side
const handleSubmit = async (e) => {
e.preventDefault();
try {
const result = await axios.get("http://localhost:5001/login", {
headers: {
// "content-type": "application/json",
"x-api-signature": "my-secret-token",
},
});
console.log(result);
} catch (error) {
console.log(error);
}
};
I am getting cors error on front end
// In Laravel auth.php
Route::get('login', [AuthenticatedSessionController::class, 'create'])
->name('login');
This route leads to a simple login page.
You can use CORS Middleware for Laravel
Or by using middleware, something like (not tested)
Note that https://stackoverflow.com should be your app domain.
class Cors
{
public function handle($request, Closure $next)
{
return $next($request)
->header('Access-Control-Allow-Origin', 'https://stackoverflow.com')
->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')
->header('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type, X-Token-Auth, Authorization');
}
}
Read
Laravel CORS Guide: What It Is and How to Enable It
Related
Just started a new project with CodeIgniter and after installation with composer I noticed the following warning in Routes.php:
// The Auto Routing (Legacy) is very dangerous. It is easy to create vulnerable apps...
So following the suggestion I set:
$routes->setAutoRoute(true);
and in Feature.php:
public bool $autoRoutesImproved = true;
My default route in Routes.php at the moment:
$routes->get('/', 'Authentication::index');
This is the Authentication controller
class Authentication extends BaseController {
public function index(): ResponseInterface {
...
return $this->response
->setBody($this->twig->render('login/view.twig'))
->setStatusCode(302);
}
public function postLogin(): ResponseInterface {
$authModel = new AuthenticationModel();
$response = $authModel->verifyLogin($_POST['loginUsername'], $_POST['loginPassword']);
return $this->response
->setBody($response)
->setStatusCode(200);
}
}
When I go to http://localhost:8080 the login page loads as it should.
I perform an AJAX request on the login page to verify the user credentials so that the latter can log in; but I am getting 404 on the following URL: http://localhost:8080/authentication/login
This is the AJAX request:
pageLoginForm.on('submit', function(e) {
let isValid = pageLoginForm.valid();
if (isValid) {
e.preventDefault();
$.ajax({
type: 'POST',
url: _baseUrl + 'authentication/login',
data: pageLoginForm.serializeArray(),
success: function (response) {
response === 'login' ? window.location.reload() : $('#errorMsg').text(response);
},
error: function () {
$('#errorMsg').text('An error occurred!');
}
});
}
});
I added the prefix "post" to my controller method as instructed by the documentation but it's not working.
Am I missing something?
It's a really frustrating issue with the pre-flight. Ajax made an options request to know if post is enebled. To solve this, make a controller to handle options requests whith:
php spark make:controller options
So modify controller in this way:
public function index()
{
return $this->optionsHandler();
}
public function optionsHandler(){
header("Access-Control-Allow-Headers: Origin, X-API-KEY, X-Requested-With, Content-Type, Accept, Access-Control-Request-Method, Access-Control-Allow-Headers, Authorization, observe, enctype, Content-Length, X-Csrf-Token");
header("Access-Control-Allow-Methods: GET, PUT, POST, DELETE, PATCH, OPTIONS");
header("Access-Control-Allow-Credentials: true");
header("HTTP/1.1 200 OK");
return die();
}
Then inside Config/Routes.php Add:
$routes->options('(:any)', 'Options::optionsHandler');
Take a look how I've implemented this in my project:
https://github.com/Akir4d/AOP
I hope this helps!
I am new with GraphQL. I need to make an API with PHP and GraphQL.
I followed this tutorial:
https://medium.com/swlh/setting-up-graphql-with-php-9baba3f21501
everything was OK, but when opening the URL, I got this error:
{
"statusCode": 405,
"error": {
"type": "NOT_ALLOWED",
"description": "Method not allowed. Must be one of: OPTIONS"
}
}
I added this to the index page :
header('Access-Control-Allow-Origin', '*');
header('Access-Control-Allow-Headers', 'content-type');
header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
but the problem wasn't resolved.
Maybe something is missing here:
return function (App $app) {
$app->options('/{routes:.*}', function (Request $request, Response $response) {
// CORS Pre-Flight OPTIONS Request Handler
return $response;
});
Error Message : Method not Allowed
Error Status Code : 405
Reason :
Actually we get this error as response to our option request not to our Post request. Browser sends option request before it sends POST, PATCH, PUT, DELETE and so on.
GraphQL declines anything that is not GET or POST so option request is declined
Solution :
Go to our cors middleware and check if its option then returns empty response with status 200. So in this way option request will never reach to GraphQL middleware
Like :
if (req.method === "OPTIONS") {
return res.sendStatus(200);
}
as
app.use((req, res, next) => {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader(
"Access-Control-Allow-Methods",
"OPTIONS, GET, POST, PUT, PATCH, DELETE"
);
res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
if (req.method === "OPTIONS") {
return res.sendStatus(200);
}
next();
});
$app = AppFactory::create();
Add
$app->setBasePath("/project/public/index.php");
I am working on a Hybrid application I want to sent json data to laravel php server using Ionic 2.
I am continuously getting error as
XMLHttpRequest cannot load http://192.168.0.101:8000/SaveUsers.
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:8100' is therefore not allowed
access.
Ionic Code:
register-recipient-page.ts
this.registrationService.sendData(this.donarDetails,this.recipientDetails).subscribe(
response => console.log(response), // success
error => console.log(error), // error
() => console.log('completed') // complete
);
Ionic Code:
registration.service.ts
sendData(recipient,donar): Observable<Object> {
let encoded_data = JSON.stringify({recipientDetails:recipient, donarDetails:donar});
let headers = new Headers();
headers.append('Content-Type', 'application/json;charset=utf-8');
headers.append('Access-Control-Allow-Origin', '*');
headers.append('Access-Control-Allow-Methods', 'GET, POST, PUT,DELETE, OPTIONS');
//let headers = new Headers({ 'Content-Type': 'application/json;charset=utf-8' });
let options = new RequestOptions({ headers: headers });
console.log(encoded_data);
return this.http.post( 'http://192.168.0.101:8000/SaveUsers',encoded_data, options).map(
(res: Response) => res.json() || {}
);
}
laravel: web.php
Route::group(['middleware' => 'cors'], function(){
Route::get('/SaveUsers', 'UserController#saveUser');
});
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');
}
I tried to do testing using simple get on the same url without sending any data, it was working fine.
Please help!!!!
I am new to Laravel and Lumen framework. I am doing my first project using Lumen. I am trying to create an API calling from angular
Here is my angular code :
app.controller('ListCtrl', ['$scope', '$http', '$location', '$window', function($scope, $http, $location, $window) {
$scope.data = {};
$scope.getdata = function() {
$scope.datas = [];
$headers = {
'Access-Control-Allow-Origin' : '*',
'Access-Control-Allow-Methods' : 'POST, GET, OPTIONS, PUT',
'Content-Type': 'application/json',
'Accept': 'application/json'
};
$http({
url: "http://localhost/service/public/getdata/",
method: "GET",
params: {'place':$scope.data.place,'pincode':$scope.data.pincode},
headers: $headers
})
.success(function(data,status,headers,config) {
$scope.datas=JSON.stringify(data);
console.log($scope.datas);
$scope.navig('/show.html');
})
.error(function(){
alert("failed");
});
};
$scope.navig = function(url) {
$window.location.href = url;
};
}]);
And here is my Lumen route.php :
<?php
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: Content-Type");
$app->get('/', function () use ($app) {
return $app->version();
});
$app->get('getdata','App\Http\Controllers\PlaceController#index');
And here is PlaceController.php
<?php
namespace App\Http\Controllers;
use App\Places;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class PlaceController extends Controller
{
public function __construct()
{
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: Content-Type");
//header("Access-Control-Allow-Origin: http://localhost:8100");
}
public function index()
{
$places = Place::all();
return response()->json($places);
}
}
But it shows "XMLHttpRequest cannot load http://localhost/service/public/getdata/?place=sdfs. Response for preflight is invalid (redirect)" error in console.log.
I have googled for two days,but cant find a solution.
Please help
You might be having problems due to invalid/incorrect Headers in your request. The only type of header that PlaceControllerseems to allow is Content-Type, but you're sending more than that.
Also, Access-Control-Allow-Origin and Access-Control-Allow-Methods headers should be added to the server response for your request, not to the request itself.
From MDN, cross-site requests (which seems to be your case) have to meet the following conditions:
The only allowed methods are:
GET
HEAD
POST
Apart from the headers set automatically by the user agent (e.g. Connection, User-Agent, etc.), the only headers which are allowed to be manually set are:
Accept
Accept-Language
Content-Language
Content-Type
The only allowed values for the Content-Type header are:
application/x-www-form-urlencoded
multipart/form-data
text/plain
Note: I never worked with Laravel or Lumen, but in my case if I don't set the headers correctly I end up with the same response for preflight is invalid (redirect) error.
This is propably something simple and obvious but I can't see where the problem is. After some research I found that in order to enable CORS in laravel 4 oen should add the following to the filters.php:
App::before(function($request)
{
if($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
$statusCode = 204;
$headers = [
'Access-Control-Allow-Origin' => '*',
'Access-Control-Allow-Methods' => 'GET, POST, OPTIONS',
'Access-Control-Allow-Headers' => 'Origin, Content-Type, Accept, Authorization, X-Requested-With',
'Access-Control-Allow-Credentials' => 'true'
];
return Response::make(null, $statusCode, $headers);
}
});
App::after(function($request, $response)
{
$response->headers->set('Access-Control-Allow-Origin', '*');
$response->headers->set('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
$response->headers->set('Access-Control-Allow-Headers', 'Origin, Content-Type, Accept, Authorization, X-Requested-With');
$response->headers->set('Access-Control-Allow-Credentials', 'true');
return $response;
});
So to my mind when one does this in angularjs:
app.factory('RestFactory', function ($http) {
var BASE_URL = 'url_to_the_site';
return {
get: function (target) {
return $http({method: 'GET', url: BASE_URL + target});
},
post: function (target, data) {
return $http.post(BASE_URL + target, data);
}
};
});
It should work right? When running Laravel 4 in localhost:8000 at development mode it seems to work. However when I transfer the Laravel to my site and try accessing the site url all I get is:
No 'Access-Control-Allow-Origin' header is present on the requested resource.
So What am I doing wrong here? It works on local, the BASE_URL also works when going to the url with a browser so what am I missing here?