0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Day21 — Reactでログイン画面を作成し、Laravel APIと連携する

Last updated at Posted at 2025-12-20

はじめに

Day20 で、

✅ ユーザー登録 API
✅ ログイン API(JWT 発行)
✅ 認証付き /me API

が完成しました。

今日はついに、

「API を実際に使う側」= フロントエンド

を実装します。

今日のゴール

・React でログイン画面を作成する

・Laravel のログイン API を叩く

・JWT を保存する

・認証付き API を呼び出す

前提構成

・フロント:React(SPA)

・バックエンド:Laravel API

・認証方式:JWT(Bearer Token)

フロント側の責務を整理

フロントの役割はシンプルです。

1.入力を受け取る

2.API に送る

3.トークンを保存

4.以降のリクエストに付与

ログイン画面を作る

import { useState } from 'react';

const Login = () => {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');

  const handleSubmit = async (e) => {
    e.preventDefault();

    const res = await fetch('http://localhost/api/login', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ email, password })
    });

    const data = await res.json();

    if (data.status === 'success') {
      localStorage.setItem('token', data.access_token);
      alert('ログイン成功');
    } else {
      alert(data.message);
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="email"
        placeholder="email"
        value={email}
        onChange={(e) => setEmail(e.target.value)}
      />
      <input
        type="password"
        placeholder="password"
        value={password}
        onChange={(e) => setPassword(e.target.value)}
      />
      <button type="submit">ログイン</button>
    </form>
  );
};

export default Login;

JWT を保存する理由

localStorage.setItem('token', token);

・ページ更新しても保持できる

・API 呼び出し時に使い回せる

※ セキュリティ注意点は Day16・17 参照

認証付き API を呼ぶ

const token = localStorage.getItem('token');

const res = await fetch('http://localhost/api/me', {
  headers: {
    Authorization: `Bearer ${token}`
  }
});

const data = await res.json();
console.log(data);

動作確認フロー

1.ログイン画面表示

2.メール・パスワード入力

3.トークン取得

4./me API 成功 🎉

👉 フロントとバックがつながった瞬間

よくあるハマりポイント

❌ CORS エラー

Access-Control-Allow-Origin

👉 Laravel 側で CORS 設定が必要
laravel-corsconfig/cors.php

❌ トークンが送られていない

Authorization: Bearer undefined

👉 localStorage のキー名を確認

❌ 401 Unauthorized

・トークン期限切れ

・Bearer の付け忘れ

実装をきれいにするコツ

・API 通信は util にまとめる

・token 取得処理を共通化

・エラーハンドリングを揃える

API 通信の共通化例

export const apiFetch = (url, options = {}) => {
  const token = localStorage.getItem('token');

  return fetch(url, {
    ...options,
    headers: {
      ...options.headers,
      Authorization: `Bearer ${token}`,
    },
  });
};

✅ 今日のまとめ

・React でログイン画面を作成した

・Laravel API と通信できた

・JWT を保存して使い回した

・認証付き API を呼び出せた

 次回 Day22

次は ログイン後の世界 です。

Day22 — 投稿一覧APIを作り、Reactで一覧表示する

「CRUD アプリ」として完成形に近づきます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?