Closed5

CodeIgniter4とReactのSPA〜申し訳程度の認証を添えて〜

wlboooooooooonwlboooooooooon

php-jwt

https://mfikri.com/en/blog/codeigniter-login-jwt

こちらのサイトを参考に設定した。

なお、バージョンが違ったのかいくつかそのままでは動作しない箇所が存在した。

JWT::decodeの差異

...
// importに下記を追加
use Firebase\JWT\Key;
...

// 引数2,3は第2引数にまとまる
// JWT::decode($token, $key, ['HS256']);
JWT::decode($token, new Key($key, 'HS256'));
wlboooooooooonwlboooooooooon

React

useAuth.ts
import { useContext } from "react";
import { AuthContext } from "./AuthContext";
import axios from "axios";

const useAuth = () => {
  const { token, setToken } = useContext(AuthContext);

  const login = async (email: string, password: string) => {
    try {
      const response = await axios.post("/api/login", {
        email,
        password,
      });
      setToken(response.data);
    } catch (error) {
      console.error("Login failed:", error);
    }
  };

  const logout = () => {
    setToken("");
    localStorage.removeItem("token");
  };

  const isTokenExpired = (token) => {
    if (!token) {
      return true;
    }

    const payload = JSON.parse(atob(token.split(".")[1]));
    const iat = payload.iat;
    const currentTime = Math.floor(Date.now() / 1000);

    return currentTime > iat;
  };

  const isLogin = !isTokenExpired(token);

  return { token, login, logout, isTokenExpired, isLogin };
};

export default useAuth;
AuthContext.tsx
import React, { createContext, useState, useEffect, ReactNode } from "react";

interface AuthContextType {
  token: string;
  setToken: React.Dispatch<React.SetStateAction<string>>;
}

export const AuthContext = createContext<AuthContextType>(
  {} as AuthContextType,
);

export const AuthProvider = ({ children }: { children: ReactNode }) => {
  const [token, setToken] = useState<string>(
    localStorage.getItem("token") || "",
  );

  useEffect(() => {
    localStorage.setItem("token", token);
  }, [token]);

  return (
    <AuthContext.Provider value={{ token, setToken }}>
      {children}
    </AuthContext.Provider>
  );
};

なお、RefreshKeyについては実装はしていない。

このスクラップは10日前にクローズされました