ポートフォリオサイトのまとめ
Portfolio Site — 設計と工夫
Next.js(フロント)と Laravel(API)で構成した個人ポートフォリオ兼ブログ設計メモです。
アーキテクチャ
- フロントエンド: Next.js(App Router)、TypeScript、Tailwind CSS
- バックエンド: Laravel(API のみ)、MySQL、Laravel Sanctum(個人アクセストークン)
- リポジトリ: フロントと API は 別リポジトリ(デプロイ・権限・ライフサイクルを分離しやすくするため)
公開向けは 読み取り中心の JSON API(プロフィール・制作物・記事・お問い合わせ POST)。管理機能は 適切に集約し、認証済みの時のみ CRUD と画像アップロードが可能にしてます。
認証・セキュリティ
アプリ層(Laravel)
- 管理 API は
auth:sanctum。ログインでトークンを発行し、以降のリクエストで検証。 - フロントは本番で Nginx の HTTP Basic 認証と同一オリジンになるため、ブラウザが
Authorization: Basicを付け、fetchのAuthorization: Bearerと衝突していたようだったので対策として:- API 側:
X-Sanctum-Tokenヘッダを受け取り、ミドルウェア内でAuthorization: Bearerに正規化してから Sanctum を通す。 - フロント側: トークンは
X-Sanctum-Tokenで送る。curl等の Bearer のみのクライアントは従来どおり動作する。
- API 側:
- API 専用アプリのため、未認証時に
route('login')へリダイレクトするとルート未定義で 500 になる。bootstrapでapi/*および JSON 期待リクエストはリダイレクト先をnullにし、401 JSON を返すようにした。
Webサーバ(Nginx)
- 管理画面以降にのみ Basic 認証をかけ、多層防御としました。
- **
.htpasswdの適切なパーミッション設定。
CORS
FRONTEND_URLとローカル(localhost/127.0.0.1)を許可し、開発と本番の両方から API を呼べるようにした。
データモデルと API 設計
- 制作物(works): 説明、リンク、デモ動画 URL、サムネイル、技術タグ(配列)、公開フラグ。
- 記事(articles): スラッグ、抜粋、本文、サムネイル、公開日、公開フラグ。本文内の画像は アップロード URL を貼り付ける運用に対応。
バリデーションでは、本番で実際に起きやすい次の点を考慮した。
- 技術タグに
next.jsのようなドットが入る → 厳しすぎるalpha_dashを避ける。 - サムネイルが 絶対 URL と
/storage/...の相対パスの両方になりうる → 両方許容し、ドメインのみの入力にはhttps://を補完する前処理を入れた。
フロントエンド
- 公開ページと管理画面でレイアウトを分離。ヘッダー/フッターをコンポーネント化し、明るめのトーンに統一。
- 環境変数:
NEXT_PUBLIC_API_BASE_URLは/api/v1まで含める。オリジンのみの設定でも クライアント側で/api/v1を補完し、誤って/admin/...に API リクエストが流れるのを防ぐ。 - 管理画面は 検索・ページネーション、記事の スラッグ自動生成、画像アップロードとタグ編集に対応。
- API 呼び出しでは
Accept: application/jsonを付与し、Laravel 側の応答形式を安定させた。
インフラ(AWS)
- 単一 EC2(例:
t3.micro)、Elastic IP、Route 53、Let’s Encrypt(Certbot)。 - Nginx: TLS 終端、
/api→ PHP-FPM(Laravel)、/と/admin→ Next.js(Node) のリバースプロキシ。 - systemd で Next.js の
next startを常駐。 - t3.microだとメモリが限られてnpm run時にクラッシュしたためメモリスワップしました。