はじめに
Day23 で、
✅ 投稿作成(Create)
✅ React から投稿送信
ができるようになりました。
残っているのは…
「編集・削除」+「誰がそれをできるのか」
今日は CRUD 完成直前の重要回 です。
今日のゴール
・投稿編集 API(Update)を実装する
・投稿削除 API(Delete)を実装する
・投稿者本人のみ操作可能 にする
・権限制御の考え方を理解する
なぜ権限制御が必要?
もし制御が無いと…
・他人の投稿を編集できる
・他人の投稿を削除できる
・API として致命的 😇
👉 「認証」+「認可」 が揃って初めて安全です。
認証 vs 認可
| 種類 | 役割 |
|---|---|
| 認証 | あなたは誰? |
| 認可 | それをやっていい? |
今日は 認可 を実装します。
ルーティング定義
routes/api.php
Route::middleware('auth:api')->group(function () {
Route::put('/posts/{post}', [PostController::class, 'update']);
Route::delete('/posts/{post}', [PostController::class, 'destroy']);
});
投稿編集 API(Laravel)
public function update(Request $request, Post $post)
{
// 権限制御
if ($post->user_id !== auth('api')->id()) {
return response()->json([
'status' => 'error',
'message' => '権限がありません'
], 403);
}
$request->validate([
'title' => 'required|string|max:255',
'body' => 'nullable|string',
]);
$post->update($request->only('title', 'body'));
return response()->json([
'status' => 'success',
'data' => $post
]);
}
投稿削除 API(Laravel)
public function destroy(Post $post)
{
if ($post->user_id !== auth('api')->id()) {
return response()->json([
'status' => 'error',
'message' => '権限がありません'
], 403);
}
$post->delete();
return response()->json([
'status' => 'success'
]);
}
なぜ 403 を返す?
403 Forbidden
・認証はされている
・だが権限が無い
👉 401 と使い分けるのが重要
React 側:編集・削除ボタン表示制御
{post.user_id === currentUser.id && (
<>
<button onClick={() => editPost(post)}>編集</button>
<button onClick={() => deletePost(post.id)}>削除</button>
</>
)}
React 側:削除処理
const deletePost = async (id) => {
const token = localStorage.getItem('token');
await fetch(`http://localhost/api/posts/${id}`, {
method: 'DELETE',
headers: {
Authorization: `Bearer ${token}`
}
});
setPosts(posts.filter(post => post.id !== id));
};
React 側:編集処理(簡易)
const updatePost = async (id, title, body) => {
const token = localStorage.getItem('token');
const res = await fetch(`http://localhost/api/posts/${id}`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${token}`
},
body: JSON.stringify({ title, body })
});
const data = await res.json();
// state 更新処理
};
サーバ側でも必ず制御する理由
❌ フロントだけ制御
→ API を直接叩けば突破可能
✅ サーバ側で最終判断
→ セキュリティ担保
よくあるミス
❌ user_id をリクエストから受け取る
👉 なりすまし可能(NG)
❌ 401 と 403 の混同
・未ログイン → 401
・権限なし → 403
今日のポイント
・CRUD の U / D を実装
・認可は必須
・投稿者本人のみ操作可能
・サーバ側チェックが最重要
今日のまとめ
・投稿編集・削除 API を実装した
・権限制御を入れた
・API として安全になった
・CRUD がほぼ完成した 🎉
次回 Day25(最終日 🎄)
ついに最終回です。
Day25 — リクエストレスポンスから学んだAPI設計まとめ&今後の学習ロードマップ
「25日間の総まとめ」+次に何を学べばいいか
を整理します。