Laravel работает как API сервис для фронта, фронт на react.
Обычные API ссылки вызываются без проблем:
https://api.dev.site.ru/api/products
Фотки находятся по адресу
https://api.dev.site.ru/images/tickets/cat.jpg
Запрос идет с адреса:
https://develop.app.site.ru/
Доступ к фотке закрыт по Bearer token.
Если я локально тестирую где у меня и бек и фронт на одном домене test.ru, то там все хорошо. Фотка отображается у нее код ответа 200.
Если я в postman открываю фотку с удаленного сайта
https://api.dev.site.ru/images/tickets/cat.jpg, то она открывается но у него код ответа почему то 404, у локальной фотки код ответа 200. И локально и удалено один и тот же сайт с одинаковыми настройками.
Убрав проверку авторизации с фотки, она открылась на сайте, но ошибка CORS осталась и по прямой ссылке в браузере она открывается с кодом 404
Файл config/cors.php:
<?php
return [
/*
|--------------------------------------------------------------------------
| Cross-Origin Resource Sharing (CORS) Configuration
|--------------------------------------------------------------------------
|
| Here you may configure your settings for cross-origin resource sharing
| or "CORS". This determines what cross-origin operations may execute
| in web browsers. You are free to adjust these settings as needed.
|
| To learn more: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
|
*/
'paths' => ['api/*', 'sanctum/csrf-cookie', 'images/*'],
'allowed_methods' => ['*'],
'allowed_origins' => ['*'],
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => false,
];
Файл app/Provited/RouteServiceProvider.php:
<?php
namespace App\Providers;
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Facades\Route;
class RouteServiceProvider extends ServiceProvider
{
/**
* The path to the "home" route for your application.
*
* This is used by Laravel authentication to redirect users after login.
*
* @var string
*/
public const HOME = '/home';
/**
* The controller namespace for the application.
*
* When present, controller route declarations will automatically be prefixed with this namespace.
*
* @var string|null
*/
// protected $namespace = 'App\\Http\\Controllers';
/**
* Define your route model bindings, pattern filters, etc.
*
* @return void
*/
public function boot(): void
{
$this->configureRateLimiting();
$this->routes(function () {
Route::prefix('api')
->middleware('api')
->namespace($this->namespace)
->group(base_path('routes/api.php'));
Route::prefix('images')
->middleware('cors')
->namespace($this->namespace)
->group(base_path('routes/images.php'));
Route::middleware('web')
->namespace($this->namespace)
->group(base_path('routes/web.php'));
});
}
/**
* Configure the rate limiters for the application.
*
* @return void
*/
protected function configureRateLimiting(): void
{
RateLimiter::for('api', function (Request $request) {
return Limit::perMinute(60)->by(optional($request->user())->id ?: $request->ip());
});
RateLimiter::for('images', function (Request $request) {
return Limit::perMinute(60)->by(optional($request->user())->id ?: $request->ip());
});
}
}
Файл config/auth.php:
<?php
return [
/*
|--------------------------------------------------------------------------
| Authentication Defaults
|--------------------------------------------------------------------------
|
| This option controls the default authentication "guard" and password
| reset options for your application. You may change these defaults
| as required, but they're a perfect start for most applications.
|
*/
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
/*
|--------------------------------------------------------------------------
| Authentication Guards
|--------------------------------------------------------------------------
|
| Next, you may define every authentication guard for your application.
| Of course, a great default configuration has been defined for you
| here which uses session storage and the Eloquent user provider.
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| Supported: "session"
|
*/
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'images' => [
'driver' => 'passport',
'provider' => 'users',
],
'api' => [
'driver' => 'passport',
'provider' => 'users',
]
],
/*
|--------------------------------------------------------------------------
| User Providers
|--------------------------------------------------------------------------
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| If you have multiple user tables or models you may configure multiple
| sources which represent each model / table. These sources may then
| be assigned to any extra authentication guards you have defined.
|
| Supported: "database", "eloquent"
|
*/
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
// 'users' => [
// 'driver' => 'database',
// 'table' => 'users',
// ],
],
/*
|--------------------------------------------------------------------------
| Resetting Passwords
|--------------------------------------------------------------------------
|
| You may specify multiple password reset configurations if you have more
| than one user table or model in the application and you want to have
| separate password reset settings based on the specific user types.
|
| The expire time is the number of minutes that each reset token will be
| considered valid. This security feature keeps tokens short-lived so
| they have less time to be guessed. You may change this as needed.
|
*/
'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60,
'throttle' => 60,
],
],
/*
|--------------------------------------------------------------------------
| Password Confirmation Timeout
|--------------------------------------------------------------------------
|
| Here you may define the amount of seconds before a password confirmation
| times out and the user is prompted to re-enter their password via the
| confirmation screen. By default, the timeout lasts for three hours.
|
*/
'password_timeout' => 10800,
];
Файл routes/images.php:
<?php
use App\Http\Controllers\ImageController;
use Illuminate\Support\Facades\Route;
Route::middleware('auth:images')->group(function () {
Route::get('tickets/{filename}', [ImageController::class, 'showTicketImage']);
});
Файл app/Http/Controllers/ImageController.php:
<?php
namespace App\Http\Controllers;
use App\Modules\Common;
use Intervention\Image\Facades\Image;
use Illuminate\Http\Request;
class ImageController extends Controller
{
/**
* Получение фотки тикета
*
* @param Request $request
* @param string $fileName
* @return mixed
*/
public function showTicketImage(Request $request, string $fileName): mixed
{
$path = storage_path(Common::TICKET_PATH . $fileName);
if (!file_exists($path))
return response('', 404);
return Image::make($path)->response();
}
}
Файл nginx стандартный который при установке nginx последней версии там добавляется.