Hi there,
I resolved my CORS issue on my Lumen API and Angular 4. Hopefully you can take some of what I have done and apply it to your project.
My project ran multiple micro-services, I had Angular 4 on my local - with Lumen API in my Docker container and AWS EFS once I made a release to production. So CORS was important for me.
I could personally not find any Lumen/Laravel package that worked for me successfully (partly because I did not enable my apache headers initially have a look to be sure you have it setup Linux: https://www.garron.me/en/bits/enable-mod-headers-apache-2.html ). In my case, I am using Docker - I had to make sure that my container allowed headers to be passed.
So I had to add RUN a2enmod headers to my Dockerfile and then restarted my container.
The chrome plugin was a temporary solution, but I could not ask my client to install the CORS plugins, so I needed a different solution.
This is what I did.
Step 1:
Make sure your server has headers enabled
Step 2:
Add a .htaccess that will allow you to give access to certain domains.
It basically allow Access-Control-Allow-Origin for all the domain names you choose in the curly brackets. I needed this security measure and only wanted to allow my Frontend Angular instance to access my API.
The last couple of lines (i.e. # Handle Authorization Header
) is only needed if you have JWT setup.
Here is the .htaccess file.
/app/public/.htaccess
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>
<IfModule mod_headers.c>
SetEnvIf Origin "http(s)?://([^.]+\.)?(mysite.com|mysite.local:4200|localhost:4200)$" AccessControlAllowOrigin=$0$1
Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
Header set Access-Control-Allow-Credentials true
</IfModule>
RewriteEngine On
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
</IfModule>
Step 3:
Then you need to handle the OPTIONS requests that are coming through. It is like a handshake, they check if the server is whitelisted and then it needs to get a reply back from the API with a 200 - to say go ahead, send you request.
All I had to do was to create a app/Http/Middleware/CorsMiddleware.php in my Middleware folder and then include it in my bootstrap/app.php
<?php
namespace App\Http\Middleware;
use Closure;
class CorsMiddleware
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
//Intercepts OPTIONS requests
if($request->isMethod('OPTIONS')) {
$response = response('', 200);
} else {
// Pass the request to the next middleware
$response = $next($request);
}
// Adds headers to the response
$response->header('Access-Control-Allow-Methods', 'HEAD, GET, POST, PUT, PATCH, DELETE');
$response->header('Access-Control-Allow-Headers', $request->header('Access-Control-Request-Headers'));
// Sends it
return $response;
}
}
Have a look at the ticket below if my solution above don't work for you: https://gist.github.com/danharper/06d2386f0b826b669552
Step 4:
Then in your bootstrap/app.php or similar in Laravel, declare your middleware to handle your CORS requests. You can do it globally, like I did it or on certain routes.
I defined mine globally.
$app->middleware([
App\Http\Middleware\CorsMiddleware::class
]);
Hope some of this helps.