プロジェクト概要
普段は電気系エンジニアとして働いていますが、趣味として1年ほど前からプログラミングを始めました。このWebアプリは個人的に初めて開発したものです
今回は主に、LaravelとReactの設定関係に焦点を当てています。
フィードバック歓迎
改善点や気になる点があれば、ぜひコメントで教えていただけると幸いです。今回紹介する内容が、他の方の参考になればと思います。
インスタグラム ハッシュタグ分析サイトはこちらで公開しています。
→ 機能やサイトの詳細は以下をご覧ください。
機能要件
このWebアプリでは、Instagram APIを活用してハッシュタグに基づくデータを収集し、分析を行います。以下に主な機能をまとめました。
-
Instagram APIの利用
指定したハッシュタグ(最大20個)に関連する投稿を毎時間取得し、1つのハッシュタグにつき1000~3000件の投稿を取得します。 -
データの表示
取得した投稿から、次のようなデータを表示します: -
ユーザーの閲覧制限
ゲストユーザーは主要なハッシュタグのみ閲覧可能。ログイン済みユーザーは全てのハッシュタグを閲覧可能(有料プランは無し)。
環境
フロントエンド
- ホスティング: Netlify
- 言語: React
サーバーサイド
- ホスティング: エックスサーバー
- 言語: Laravel11
- データベース: MySQL
その他
- バージョン管理: GitHub
- ローカル開発: Docker
ドメイン設定
このアプリは「お名前.com」で取得したドメイン「trend-tagger.com」を使用しています。設定は以下の通りです。
Netlify側 (メインドメイン)
ホスト名 | 種別 | 内容 | TTL | 優先度 |
---|---|---|---|---|
api.trend-tagger.com | A | エックスサーバー側のIPアドレス | 3600 | 0 |
あらかじめNetlifyにドメインを登録する必要があります。参考記事はこちら: Netlifyドメイン登録
エックスサーバー側 (サブドメイン)
ホスト名 | 種別 | 内容 | TTL | 優先度 |
---|---|---|---|---|
api.trend-tagger.com | A | エックスサーバー側のIPアドレス | 3600 | 0 |
www.trend-tagger.com | CNAME | trend-tagger.netlify.app | 3600 | 0 |
サーバー側の環境構築
サーバー側ではPHPのバージョン管理や、Composerのインストールを行っています。以下に具体的な手順を記載します。
PHPバージョン変更
SSH接続が必要です。接続方法についてはエックスサーバーSSH接続を参考にしてください。
- ホームディレクトリに「bin」フォルダを作成します。
mkdir $HOME/bin
- シンボリックリンクを作成します(
whereis php
コマンドで存在するPHPバージョンを確認)。
ln -s /usr/bin/php8.3 $HOME/bin/php
- vimを開く
vi ~/.bashrc
- 開いたvimの最終行に追加(:wで上書き、:qで終了)
export PATH=$HOME/bin:$PATH
- 変更内容を反映
source ~/.bashrc
Composerのインストール
- SSH接続後に、以下のコードを使ってComposerをインストールします。
Composer公式サイトにて最新バージョンのインストールコードを確認してください。
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php -r "if (hash_file('sha384', 'your_hash_value') === 'your_hash_value') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
php composer-setup.php
php -r "unlink('composer-setup.php');"
Laravel設定抜粋
Laravel11とフロントエンドとの認証設定について、特に困った点をまとめました。
これらの設定は、Laravel11でのAPI認証では必須かと思います。
Kernel.phpというファイルは存在しないので注意が必要です
(記事を調べるとよく出てきますが、過去のLaravelバージョンで使用されていたようです)
config > cors.php
<?php
return [
'paths' => ['api/*', 'sanctum/csrf-cookie'],
'allowed_methods' => ['*'],
'allowed_origins' => ['https://trend-tagger.com'],
'allowed_headers' => ['*'],
'supports_credentials' => true,
];
bootstrap > app.php
<?php
use Illuminate\Foundation\Application;
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__ . '/../routes/web.php',
api: __DIR__ . '/../routes/api.php'
)
->withMiddleware(function ($middleware) {
$middleware->statefulApi(); // この記述が重要です!
})
->create();
routes > api.php の抜粋
// ユーザー登録処理へのルート
Route::post('/register', [RegisterController::class, 'register']);
// フロントエンドから人気投稿のリクエスト要求された時に返すためのルート
Route::get('/top-posts/secure/{hashtag}', [PostController::class, 'getTopPostsByHashtag'])->middleware('auth:sanctum');
middleware('auth:sanctum') この記述によって、フロントエンドとサーバーサイドとのユーザー認証を行っているようです。
React記述抜粋
src > components > auth > Register.js (ユーザー登録処理)
import React, { useState } from "react";
import axios from "axios";
import { useNavigate } from "react-router-dom";
import GoogleLoginButton from "./GoogleLoginButton";
import { getCookie } from "../../utils/cookies";
const Register = () => {
const [username, setUsername] = useState("");
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [passwordConfirmation, setPasswordConfirmation] = useState("");
const [errors, setErrors] = useState({});
const navigate = useNavigate();
const handleSubmit = async (e) => {
e.preventDefault();
const csrfToken = getCookie("XSRF-TOKEN");
try {
await axios.post(
"/api/register",
{ username, email, password, password_confirmation: passwordConfirmation },
{ headers: { "X-XSRF-TOKEN": csrfToken } }
);
localStorage.setItem("user", JSON.stringify({ username }));
navigate("/success");
} catch (error) {
setErrors(error.response?.data?.errors || {});
}
};
return (
<div>
<h2>新規登録</h2>
<form onSubmit={handleSubmit}>
<input type="text" value={username} onChange={(e) => setUsername(e.target.value)} required />
<input type="email" value={email} onChange={(e) => setEmail(e.target.value)} required />
<input type="password" value={password} onChange={(e) => setPassword(e.target.value)} required />
<input type="password" value={passwordConfirmation} onChange={(e) => setPasswordConfirmation(e.target.value)} required />
{Object.keys(errors).length > 0 && <div>{Object.values(errors).map((error, index) => <p key={index}>{error}</p>)}</div>}
<button type="submit">登録</button>
</form>
<GoogleLoginButton />
</div>
);
};
export default Register;
withXSRFToken: true
の記述がないと、認証に失敗します。
最後に
今回はLaravel11とReactを使って開発したアプリについて、設定面を中心に記載しました。気になる部分やご意見があれば、ぜひコメントいただけると嬉しいです。
リクエストなどあれば、処理側のコードも紹介したいと思います
参考
https://takayyz.com/blog/configure-customdomain-on-netlify/
https://hiro8blog.com/connect-to-xserver-by-ssh/
https://qiita.com/kensukeX/items/a045c5b4ecec033425d4
https://getcomposer.org/download/