Apps

012-Login+Graph|Step5_React×FastAPI:APIを使ってログイン機能を実装する

はじめに

ReactとFastAPIを統合し、実際にログイン機能を実装します。

本記事では、フロントエンドからバックエンドのAPIを呼び出し、認証処理を行う流れを詳しく解説します。

フルスタック開発の基礎を押さえながら、実践的なログイン機能を構築しましょう。

APIエンドポイントの変更

  • 修正前: https://jsonplaceholder.typicode.com/users(仮のデータを取得)
  • 修正後: http://127.0.0.1:8000/login/(ローカルのバックエンドAPI)

理由:
jsonplaceholder.typicode.com はテスト用のダミーAPIなので、実際のバックエンドAPI(FastAPIなど)と連携するためにローカルのエンドポイントに変更。

リクエスト方法の変更

  • 修正前: axios.get(endpoint, { params: { username: user.username, id: user.password } })
  • 修正後: axios.post(endpoint, { username: user.username, password: user.password })

理由:
GET リクエストは通常データの取得に使用し、ログインのような認証処理では POST を使うのが一般的。

レスポンスデータの処理

  • 修正前: response.data[0] === undefined でログイン成功・失敗を判定
  • 修正後: res.data を受け取り、ログイン成功時に setLoginUser を更新

理由:

  • jsonplaceholder.typicode.com/users は配列を返すが、実際のAPIは {"token": "xxxx", "username": "test_user"} のような JSON を返す可能性が高いため。
  • response.data[0] のような処理は不要になる。

React Router の navigate の変更

  • 修正後: navigate("/", { state: { username: user.username } }) を追加。

理由:

  • ログイン後、useLocation を使って username を取得できるようにするため。

まとめ

修正後のコードでは、以下のような流れでログイン処理が行われる:

  1. POST リクエストを http://127.0.0.1:8000/login/ に送信
  2. バックエンドが認証し、成功すれば setLoginUserusername を保存
  3. ログイン成功時に navigate("/") でトップページへ移動
  4. ログイン失敗時に navigate("/loginfailed") でエラーページへ移動

これで、実際のバックエンドと連携するログイン処理になります

useLogin.js

import React from 'react'
import { useContext } from 'react';
import { useNavigate } from 'react-router-dom';
import axios from "axios";
import { LoginUserContext } from '../providers/LoginUserProvider';


export const useLogin = () => {
    const { setLoginUser, setIsLogined } = useContext(LoginUserContext);
    const navigate = useNavigate();
    const login = (user) => {
        console.log("ログイン処理開始");
        const endpoint = "http://127.0.0.1:8000/login/"
    
        axios
        .post(endpoint, {
            username: user.username,
            password: user.password,
        })
        .then(res => {
            console.log(res.data);
            console.log("ログイン成功");
            setLoginUser(user.username);
            setIsLogined(true);
            navigate("/", {state: {username: user.username}});
        })
        .catch(error => {
            console.error("ログイン失敗", error);
            navigate("/loginfailed");
        });
    };

  return {login}
}

動作確認

-Apps