My simple web application consists of a Laravel API as backend and a React App as frontend. The application is accessible through https://example.com and makes requests to https://api.example.com. Therefore only requests from the frontend should be allowed.
So, I have already updated the CORS configuration in config/cors.php
of the backend like this:
'allowed_origins' => ['https://example.com'],
However, this does not restrict direct access to the API through https://api.example.com, which is unfortunately still possible.
Is there a way to do both, restricting direct access and allowing requests only from the frontend?
CodePudding user response:
You can lock down your API and grant access to your frontend via Laravel Sanctum's "API Token Authentication".
CodePudding user response:
You can try to add a custom global http header, to the requests made from the react app to the backend.
For eg: In axios you can set custom global header
axios.defaults.headers.common['x-spa-custom'] = 'my-custom-value';
Then in the Laravel backend, you may define a middleware to check for the presence of custom header
<?php
namespace App\Http\Middleware;
class EnsureIsFromSpa extends Middleware
{
/**
* Check if the incoming request is from react frontend.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return string|null
*/
protected function handle($request, $next)
{
if ($request->hasHeader('x-spa-custom') && $request->header === 'my-custom-value') {
return $next($request);
}
//Can even throw a custom exception here and handle via the App\Exceptions\Handler
//Or redirect to home page
return redirect('/');
}
}
Then you can apply EnsureIsFromSpa
to the routes which you want to protect (kind of) from access other than react frontend.
Note: This isn't a robust solution which can't be circumvented, Making requests via Postman or curl people can still add the header and access the "protected" pages if they figure out the missing custom header.