CORS issue with laravel rest api POST - laravel

Failed to load https://example.com/api/api_details: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://example-international.firebaseapp.com' is therefore not allowed access.
That is my error when requesting a POST method. But its perfectly alright when it was in local and i put these line in header on laravel function:
header('Access-Control-Allow-Origin: *');
I also tried these for online:
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE, PUT');
But no luck. All the post and get request are okay in local but in online only get request works. I am using angular 6 and laravel 5.3.
here is my network tab given bellow:

Use this package inside your Laravel application.
https://github.com/barryvdh/laravel-cors
It's very simple and will solve your problem.
Just don't forget to publish the config file using:
$ php artisan vendor:publish --provider="Barryvdh\Cors\ServiceProvider"

create a cors middleware and replace your handle method with
public function handle($request, Closure $next)
{
return $next($request)
->header('Access-Control-Allow-Origin', '*')
->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')
->header('Access-Control-Allow-Headers', 'Accept, Authorization, Content-Type');
}

Building web applications with Microservices Architecture comes with a couple of fixable issues. One of such issues is CORS. Most commonly, you face this issue when you try to test decoupled applications locally on your machine.
Say we had a RESTful API built with Laravel and a SPA built with VueJS, attempting to make a request from the Vue App running on port 8080 to the Laravel backend running on PORT 8000 might lead to an error like such:
[Check Error:][1]
[1]: https://i.stack.imgur.com/rGMmS.png
Thankfully, we can fix this easily in Laravel with the Laravel-cors package.
Installation
The Laravel-Cors package can be installed using composer. Navigate to your Laravel application folder in the terminal and run:
composer require fruitcake/laravel-cors
Configuration
After a successful installation, you should now have the Laravel-cors package added to your packages, you can check that you have it in your composer.json file.
"fruitcake/laravel-cors": "^1.0",
Next, we’ll need to add the HandleCors middleware in the $middleware property of app/Http/Kernel.php class. Open app/Http/Kernel.php and add this line in the $middleware property.
protected $middleware = [
...
\Fruitcake\Cors\HandleCors::class, # this line
];
Finally, we need to publish the package so the configuration file can be copied from the package directory to our application directory.
php artisan vendor:publish --tag="cors"
A new file (config/cors.php) should be added to your config folder. This file should contain default configurations for CORS. You can use the default configuration or tweak it however you wish. Let’s dig in a bit and see what options this file provides us.
<?php
return [
'paths' => [],
'allowed_methods' => ['*'],
'allowed_origins' => ['*'],
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => false,
'max_age' => false,
'supports_credentials' => false,
];
paths: This option takes an array value and allows us to enable cors for multiple paths. Some example configurations would be:
'paths' => ['api/*', 'api/admin/*', 'api/users/*', '*']
allowed_methods: This option indicates what HTTP request methods to allow on the specified paths. [*]allows all methods. Some examples of option values would be:
'allowed_methods' => ['POST', 'GET', 'DELETE', 'PUT', '*']
allowed_origins: This option specifies what source requests should be allowed from. If you would want to test from your local machine, you would have to add “localhost” + the port to the list of allowed origins.
'`enter code here`allowed_origins' => ['http://localhost:8080', 'https://client.myapp.com']
allowed_origins_patterns: This option matches the request origin with patterns.
'allowed_origins_patterns' => ['Google\']
allowed_headers: This option is used to set the Access-Control-Allow-Headers, which is used in response to a preflight request which includes the Access-Control-Request-Headers to indicate which HTTP headers can be used during the actual request.
'allowed_headers' => ['X-Custom-Header', 'Upgrade-Insecure-Requests', '*']
exposed_headers: This option is used to set the value of Access-Control-Expose-Headers response header. This response header indicates which headers can be exposed as part of the response by listing their names.
max_age: This option is used to set the Access-Control-Max-Age response header. The Access-Control-Max-Age response header indicates how long the results of a preflight request ( the information contained in the Access-Control-Allow-Methods and Access-Control-Allow-Headers headers) can be cached.
supports_credentials: This option sets the Access-Control-Allow-Credentials header. The Access-Control-Allow-Credentials response header tells browsers whether to expose the response to frontend JavaScript code when the request's credentials mode (Request.credentials) is included.
Now we have an understanding of the function of each of the options. You can configure these options however you want. Once you’re done, you want to reload your Laravel configurations and allow your changes to reflect.
php artisan config:cache
This should clear your configuration cache and recache the updated configurations (including your changes). From here you can serve your application.
php artisan serve
I hope this post helps you resolve any of your Laravel CORs issues.
Cheers 🍻

Related

Laravel Sanctum unauthenticated using postman

I follow the Laravel official document step by step.
When I send a request to {{host}}/api/login, I can receive the response that includes the token. Everything is correct.
But when I try to send a request to {{host}}/api/user, it is always unauthenticated.
I checked my code several times, I cannot fix it.
In my .env file, I set as following, my backend host is http://laravel_8_api.test
SESSION_DOMAIN=.laravel_8_api.test
SANCTUM_STATEFUL_DOMAINS=.laravel_8_api.test
How can I make it work? Please help me.
The code is in this link https://github.com/ramseyjiang/laravel_8_api
Try this if you haven't
The reason this isn't working is that Sanctum is denying the authenticated request based on the referrer.
Add Referer to the request header in postman.
//api.php
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
return $request->user();
});
middleware should be auth:sanctum instead of auth:api
In the official document, it forgets to modify the config/auth.php
'api' => [
'driver' => 'sanctum',
'provider' => 'users',
'hash' => false,
],
After that, it will fix this issue.
Don't need to modify code in the code in the api.php
I mean it doesn't need to change auth:sanctum to the auth:api, if change it, it will make another issue as the link Laravel Sanctum : column not found: 1054 Unknown column 'api_token' in 'where clause'
Try this solution, may it will help you.(It helped me)
first you check is that your bearer token which you sending in header is really reaching to your app server?
Lets check it:
put this code in your route/api.php file
print_r($_REQUEST);
print_r($_SERVER);
exit;
now lets send postman request,
in response you will get a line like this
"[REDIRECT_HTTP_AUTHORIZATION] => Bearer 6|4rxthBID7kiSleFglD30aphZu3poiDYJjWMJgZZc"
if this line is missing then its mean your .htaccess file is not allowing to pass token to server.
So the solution is very easy, just add this line to your .htaccess file
#Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

404 Not Found on sanctum/csrf-cookie path

So I've been building a projet based on laravel. I'm building on a SPA foundation with sanctum as my authorization package. It works perfectly. Then I deploy the project to the server and everytime I try to login there is a 404 error on /sanctum/csrf-cookie.
How could this happen? Is it because the SanctumServiceProvider not working.
The problem is when you define sanctum prefix, the route become something else like this:
you can check your routes with : php artisan route:list
as you can see the /sanctum/ is removed and when you check the route /sanctum/csrf-cookie it will not be and throws 404 error. So you have two options:
add this prefix: 'prefix' => 'api/v1/sanctum'
or
change GET call to api/csrf-cookie
You need to check if you're setting correct axios defaults for your /sanctum/csrf-cookie api call.
You can set it as follows
axios.defaults.withCredentials = true;
axios.defaults.baseURL = "http://localhost"; //Before sending get request
axios.get("/sanctum/csrf-cookie").then(async () => {
//Logic to handle login
});
If defaults are not set properly url becomes http::localhost::8080/sanctum/crf-cookie which is where frontend is serving but instead it has to be http::localhost/sanctum/csrf-cookie
Note: localhost example is just for explanation. For production server make sure your url is correct and api call is on backend.
I solved this issue by adding:
AllowOverride All
to the apache directory config
add in last line inside config/sanctum.php
'routes' => false,
Add in config/cors.php
'paths' => ['*']

CORS Error in Laravel 7 using Laravel Lighthouse

I have an API built with Laravel and Lighthouse-php(for GraphQL). My client is built with Vue js and uses Apollo for the graphQL client-side implementation. Anytime I make a request, I get the following error:
Access to fetch at 'http://localhost:8000/graphql' 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.
Naturally, I proceeded to install laravel-cors package but I realized afterwards that it came by default with my Laravel installation (7.2.2). Which meant that \Fruitcake\Cors\HandleCors::class was already added to the middleware array in Kernel.php and the cors config file was already in my config directory.
After some googling, I realized that I needed to add \Fruitcake\Cors\HandleCors::class to the route.middleware array in my config/lighthouse.php file
It still did not work. I have restarted the server, cleared cache, cleared config and run composer dump-autoload but I still get the error. I have no idea how to get past this. Any help will be appreciated.
Versions
Laravel 7.2.2
Laravel Lighthouse 4.10
I got some help from the folks at lighthouse here. The problem was with my cors configuration. I needed to add graphql to the path array in config/cors but I mistakenly added graphql/*. So the path array looked like this
'paths' => ['api/*', 'graphql/*'],
instead of this
'paths' => ['api/*', 'graphql'],
After making the changes, I run the following:
php artisan cache:clear, php artisan config:clear and composer dump-autoload before the CORS error was gone.
The full configuration that worked for me was
return [
'paths' => ['api/*', 'graphql'],
'allowed_methods' => ['*'],
'allowed_origins' => ['*'],
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => false,
'max_age' => false,
'supports_credentials' => false,
];

How to fix 'The GET method is not supported for this route. Supported methods: POST'

I'm developing a REST service with Laravel to consume it from a mobile app. It works properly on local, but not on hosting. After several tries, I developed a basic example to test the POST method, but it returns the same error.
api.php file
Route::post('/test', 'testController#test') ;
testController.php file
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class testController extends Controller
{
//
public function test(Request $request)
{
return response()->json(['mensaje' => 'POST access successful']);
}
}
POST request is always returning the same error, and I am using POST on petition: 405 Method Not Allowed. The GET method is not supported for this route. Supported methods: POST.
POSTMAN request
I have investigated this topic and I have read it could be due CORS. So, I have installed spatie/laravel-cors with its default config, but POSTMAN is still showing the same error. Some help, please?
SOLVED:
Thanks all! Definitely, it was not a CORS problem. My hosting server makes a redirect by default, losing POST parameters in the way.
If you have come across this error while using POSTMAN, you need to go into the "Settings" part of your route's parameters and disable 'Automatically follow redirects'.
Sometimes the problem arises when you have trailing froward slash.
For example:
https://somedomain.com/api/test/
Simply remove the trailing forward slash so the url will be
https://somedomain.com/api/test
It's sometimes because you're using 'http' on an 'https'-based endpoint. Try replacing the http with https.
This is because of CORS (Cross Origin Resource Sharing) is protected and you are not allow to call your api from other origin. To allow put below header setting to your routes in api.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');
Are you sure you call /api/test because in api.php route file there is a prefix on routes

Adding Access-Control-Allow-Origin to Laravel

The app in question (I am simply trying to maintain/bug fix - I am not the author) (Laravel 5.1.7) needs to call JavaScript located at s7.addthis.com. This is currently not working and is returning a Cross-Origin Request Blocked error. After doing some research, I found barryvdh/laravel-cors which seems to be the preferred method for addressing this problem. However, I believe that I have followed all of the instructions, but the Access-Control-Allow-Origin is not appearing in the output.
These are the steps I followed (I am a Laravel novice...):
composer require barryvdh/laravel-cors 0.7.x
composer update
cp vendor/barryvdh/laravel-cors/config config (did not customize)
Added 'Barryvdh\Cors\ServiceProvider', to the $providers array in config/app.php
Added 'Barryvdh\Cors\HandleCors', to the $middleware array in app/Http/kernel.php
php artisan vendor:publish --provider="Barryvdh\Cors\ServiceProvider"
The header is still not being added to the output, i.e., the errors persists. What step did I miss and/or what did I do wrong?
In an attempt to just things working, I tried adding the following to the top of bootstrap\app.php
// allow origin
header('Access-Control-Allow-Origin: *');
// add any additional headers you need to support here
header('Access-Control-Allow-Headers: Origin, Content-Type');
but this too had no effect.
I did see this post: http://en.vedovelli.com.br/2015/web-development/Laravel-5-1-enable-CORS/, which looks straight-forward enough, but in my app, the javascript is called in this manner: {!! Html::script('//s7.addthis.com/js/300/addthis_widget.js#pubid=xxx', array('async' => 'async')) !!} and I do not know how to cast this into the form shown.
Thank you.
In response to SSahut:
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
'Barryvdh\Cors\HandleCors',
];

Resources