APIのCORSでハマってました。。。
以下、備忘録。。。
バックエンド
1.本番のフォルダ構成に変更
publicフォルダ以外のフォルダを本番環境のpublic_html(公開)フォルダに置かない。
/laravel-core/ ……public以外のフォルダとファイル
/public_html/laravel-public/ ……public内のファイル
public/index.phpのパスの変更
__DIR__.'/../../laravel-core/storage/framework/maintenance.php'
__DIR__.'/../../laravel-core/vendor/autoload.php'
__DIR__.'/../../laravel-core/bootstrap/app.php'
app/providers/AppServiceProvider.phpのpublicフォルダのパスの変更
public function register(): void
{
$this->app->bind('path.public', function () {
return base_path('../public_html/laravel-public');
});
}
2..envファイルの本番環境の情報に書き換え
バックエンドhttps://domein.com、フロントエンドhttps://sub.domein.comとして。
APP_DEBUG=false
APP_URL=https://domain.com
FRONTEND_URL=https://sub.domein.com
CORS_ALLOWED_ORIGINS=https://sub.domein.com,https://domein.com
SANCTUM_STATEFUL_DOMAINS=sub.domein.com,domein.com
SESSION_DOMAIN=.sub.domein.com
DB_CONNECTION=mariadb
DB_HOST=【DBホスト】
DB_PORT=【ポート】
DB_DATABASE=【DB名】
DB_USERNAME=【ユーザー名】
DB_PASSWORD=【パスワード】
3.サーバーへの個別対応
フリーサーバーでapiフォルダおよびURLが使えないと判明した為、routes/api.phpの内容をrutes/web.phpに移す。
Route::post('/custom-url', [CustomApiController::class, 'store']);
4.本番環境の為のCORSの修正
config/cors.phpを本番環境用に修正。
allowed_origins(CORS_ALLOWED_ORIGINS)にバックエンドのURLを入れているのは念のためです。
return [
'paths' => ['api/*', 'sanctum/csrf-cookie', 'custom-url'],
'allowed_methods' => ['*'],
'allowed_origins' => explode(',', env('CORS_ALLOWED_ORIGINS', 'http://localhost:8000')),
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => true,
];
| 設定項目 | 詳細 |
| paths | CORSを適用するURIパターン |
| allowed_methods | 許可するHTTPメソッド |
| allowed_origins | アクセスを許可するオリジン ※末尾のスラッシュに注意 |
| allowed_origins_patterns | 正規表現によるオリジン指定 |
| allowed_headers | 許可するリクエストヘッダー |
| exposed_headers | ブラウザ側(JavaScript)で読み取りを許可するレスポンスヘッダー |
| max_age | プリフライト(OPTIONS)リクエストの結果をキャッシュする秒数 |
| supports_credentials | Cookieや認証情報(Authorizationヘッダーなど)の送信を許可するかどうか |
bootstrap/app.phpのミドルウェアに記述を追加。
->withMiddleware(function (Middleware $middleware): void {
$middleware->prepend(\Illuminate\Http\Middleware\HandleCors::class);
$middleware->preventRequestForgery(except: [
'*/custom-url',
]);
})
| メソッド | |
prepend(\Illuminate\Http\Middleware\HandleCors::class) | CORS制御を行うための組み込みミドルウェアをグローバルミドルウェアの最初に実行されるよう追加 |
preventRequestForgery(except: [...]) | CSRF 保護(preventRequestForgery)の除外 ※1 |
※1 以下のURLの場合はCSRF 保護の除外が可能。
- 外部サービスからのWebhook受信: Stripe、PayPal、LINE、GitHubなど、外部システムからデータを受け取るURL。
- 外部に公開するAPIエンドポイント: クッキーによるセッション認証を使わず、APIトークン(
SanctumやPassportなど)で認証を行うURL。
5.Laravelのデプロイ前のコマンド
ライブラリをインストール
composer install --no-dev --optimize-autoloader
| オプション | 詳細 |
--optimize-autoloader | SR-4などのオートローダーをクラスマップ方式に変換し、静的なクラスマップを生成。クラスを読み込むたびにファイルシステムを検索する処理を省くため、実行速度が向上。 |
--no-dev | require-dev に記載されている開発用パッケージ(テストツールやデバッグツールなど)のインストールをスキップし、除外。不要なコードを本番環境に入れないためのセキュリティと軽量化につながる。 |
Windows11のスマートアプリコントロールが以下のファイルをブロックしてしまい、Warningになってしまいますが、実行は正常に完了するので無視。
PHP\8.5.12-1\nts\x64\ext\php_zip.dll
キャッシュのクリア
そのまま行うとエラーが出てしまうので一旦、.envの以下の値をdatabeseからfileに書き換える
CACHE_DRIVER=file
SESSION_DRIVER=file
以下のコマンドでキャッシュのクリア後、.envを戻しておく。
php artisan optimize:clear
Windows11のスマートアプリコントロールが以下のファイルをブロックしてしまい、Warningになってしまいますが、実行は正常に完了するので無視。
PHP\8.5.12-1\nts\x64\ext\php_zip.dll
キャッシュの作成
php artisan optimize
以下のコマンドが順番に実行され、キャッシュファイルが生成されます。
| コマンド | 詳細 |
php artisan config:cache | 設定ファイル(config/*.php)を1つのファイルにまとめ、読み込みを高速化。 |
php artisan event:cache | イベントとリスナーの対応関係をキャッシュします。 |
php artisan route:cache | ルーティング(routes/*.php)をキャッシュし、大量のルートがある場合の登録処理を高速化。 |
php artisan view:cache | Bladeテンプレートを事前にコンパイルし、リクエスト時のコンパイル処理を省く。 |
Windows11のスマートアプリコントロールが以下のファイルをブロックしてしまい、Warningになってしまいますが、実行は正常に完了するので無視。
PHP\8.5.12-1\nts\x64\ext\php_zip.dll
6.本番環境にアップロード
FTPでもファイルマネージャでも。フリーサーバーなのでSSHでコマンドを叩けない!
以下のフォルダ(実際にあったもののみ掲載)を削除。
| 対象(ファイル/フォルダ) | 理由・注意点 |
|---|---|
tests/ | ユニットテスト用のコードです。本番の動作には不要です。 |
storage/logs/*.log | ローカルのエラーログ |
storage/framework/cache/data/* | ローカルのキャッシュ |
storage/framework/sessions/* | ローカルのセッションデータ |
storage/framework/views/* | コンパイル済みのBladeキャッシュ |
bootstrap/cache/*.php | ローカルのパス情報が含まれるため、削除 |
resources/js/resources/css/vite.config.jspackage.jsonpackage-lock.jsonphpunit.xml.editorconfig.gitattributes.env.exampleAGENT.md | 開発者向けのドキュメントやツール設定ファイル。 |
7.ウェブサーバーからの書き込み許可
strageフォルダとbootstrap/chacheフォルダの権限を775(書き込み可能)に変更
8.アクセスの変更
public_html/.htaccessの変更。
# 既存のセキュリティ設定(これだけ残す)
SetEnvIf Request_URI ".*" WpCommentDeny
RewriteEngine On
# 常時SSL化(HTTPS転送)
RewriteCond %{HTTPS} !on
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# Laravel標準のルーティング
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
9.Cron設定
一応したけど、、不要でした。
以下、サーバーのコントロールパネルで毎分に設定。
/usr/bin/php /home/【サーバーID】/【プロジェクトパス】/artisan schedule:run >> /dev/null 2>&1
| Cron設定の要不要 | ケース |
| 必要 | メールの一斉送信、データベースの定期バックアップ、期限切れデータの自動削除など、routes/console.php に定期実行タスクを定義している場合。 |
| 不要 | 通常のWebページ表示やフォーム送信など、ユーザーからのアクセスに応じた処理のみを行う場合。 |
フロントエンド
1.APIのURLを本番環境のものに変更。
fetchの記述例。バックエンドhttps://domein.com、フロントエンドhttps://sub.domein.comとして。
const baseURL = "https://domein.com";
fetch(`${baseURL}/laravel-public/custom-url`, {
method: 'POST',
mode: "cors",
cache: "default",
credentials: 'include',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
},
body: JSON.stringify(data)
})
.then(response => {
if (!response.ok) {
throw new Error('サーバーエラーが発生しました');
}
return response.json();
})
.then(data => {
console.log('成功:', data);
})
.catch(error => {
console.error('エラー:', error);
});
});
2.本番用のdistファイルを作成
ビルドして本番用のファイル作成。
npm run build
生成されたdistフォルダの中身をフロントエンドのサーバーへアップロード。
3.再読み込み時に404エラーを出さないようにアクセスを設定
フロントエンドのサーバーのindex.htmlを置く場所に.htaccessファイルを作成。
Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-do
RewriteRule ^ index.html [L]
すんごい時間かかった~~漏れがあるかもだけど、、一旦、UP!