admin管理员组

文章数量:1402802

I’m trying to manage the security of my Laravel 8 API application with Spatie Permissions. I’ve created a function that loads the permissions of a user, and I retrieve them on the frontend using React.js 18. I compare them with the permissions set in the routes, but when I debug on the frontend, I see that the permissions array is empty at first, and the route access is already blocked even though the permissions are reloaded later. However, the access remains blocked.

Thank you in advance for your time and assistance! I really appreciate any help or guidance you can provide

function that retrieves permissions from my Laravel API

public function getUserPermissions($userId = null): JsonResponse
{
    if (!$userId || $userId == 0) {
        return response()->json([
            'roles' => ['guest'],
            'permissions' => [
                'view-category', 'view-product', 'view-option',
                'view-order', 'create-order', 'view-product-option',
                'view-order-product', 'view-cart', 'create-cart',
                'delete-cart', 'add-products-to-cart', 'create-order-from-cart',
                'make-stripe-payment'
            ],
        ]);
    }

    if (!User::where('id', $userId)->exists()) {
        return response()->json(['error' => 'Utilisateur introuvable'], 404);
    }

    $user = User::with('roles')->find($userId);

    $cacheKey = "user_permissions_{$userId}";
    $permissions = Cache::remember($cacheKey, 3600, function () use ($userId) {
        return DB::table('permissions')
            ->join('model_has_permissions', 'permissions.id', '=', 'model_has_permissions.permission_id')
            ->where('model_has_permissions.model_id', $userId)
            ->pluck('permissions.name');
    });
    Log::info('test', ['$permissions' => $permissions]);
    return response()->json([
        'roles' => $user->roles->pluck('name'),
        'permissions' => $permissions,
    ]);
}

Routes API

Route::group(['prefix' => 'user'], function () {
    Route::get('/', [UserController::class, 'index'])->middleware('permission:view-user');
    Route::get('{user}', [UserController::class, 'show'])->middleware('permission:view-user');
    /*Route::post('/', [UserController::class, 'store'])->middleware('permission:create-user');*/
    Route::put('{user}', [UserController::class, 'update'])->middleware('permission:update-user');
    Route::delete('{user}', [UserController::class, 'destroy'])->middleware('permission:delete-user');
});

UserService in react js

        import axios from "axios";

const API_URL = "http://127.0.0.1:8000/api";

const userService = () => {
const fetchPermissions = async (userId, setRoles, setPermissions, setLoading) => {
    let isMounted = true;

    const safeUserId = userId ? userId : 0;

    try {
        const response = await 
       axios.get(`${API_URL}/auth/user/${safeUserId}/permissions`);

        if (isMounted) {
            setRoles(response.data.roles || []);
            setPermissions(response.data.permissions || []);
        }
    } catch (error) {
        console.error("Erreur lors de la récupération des permissions", error);
    } finally {
        if (isMounted) setLoading(false);
    }

    return () => {
        isMounted = false;
    };
};

return { fetchPermissions };
};

export default userService;

The Hook that I manage the permissions

import { useState, useEffect } from "react";
import userService from "../Services/UserService";
import useAuth from "./useAuth";

const usePermissions = () => {
const { auth } = useAuth();
const [roles, setRoles] = useState([]);
const [permissions, setPermissions] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);

useEffect(() => {
    let isMounted = true;
    const userId = auth?.user?.id;
    console.log(userId);

    if (!userId) {
        console.log("ID utilisateur est vide, requête avec un ID égal à 0");
    }

    const fetchPermissions = async () => {
        setLoading(true);
        try {
            await userService().fetchPermissions(userId, setRoles, setPermissions, 
        setLoading);
        } catch (error) {
            setError("Erreur lors de la récupération des permissions");
        }
    };

    fetchPermissions();

    return () => {
        isMounted = false;
    };
}, [auth?.user?.id]);
return { roles, permissions, loading, error };
};

export default usePermissions;


privateRoute 
import React, { useEffect, useState } from "react";
import { Navigate } from "react-router-dom";
import useAuth from "../Hooks/useAuth";
import usePermissions from "../Hooks/usePermissions";

const PrivateRoute = ({ permission, children }) => {
const { permissions, loading } = usePermissions();
const { auth } = useAuth();
const [isReady, setIsReady] = useState(false);

useEffect(() => {
    if (!loading) {
        setIsReady(true);
    }
}, [loading]);

if (!isReady) {
    return <div>Chargement...</div>;
}

console.log("Permissions de l'utilisateur:", permissions);
console.log("Permission requise:", permission);
console.log("Les permissions sont-elles chargées ?", isReady);

if (!isReady) {
    return <div>Chargement...</div>;
}

if (!auth?.user) {
    console.log("Aucun utilisateur connecté. Redirection vers /");
    return <Navigate to="/" />;
}

if (permission && !permissions.some(perm => perm.trim().toLowerCase() === 
permission.trim().toLowerCase())) {
    console.log("Permission refusée. Redirection vers /not-authorized");
    return <Navigate to="/not-authorized" />;
}

return children;
};

export default PrivateRoute;

App.js

function App() {

  return (
  <Routes>
      <Route path="/" element={<Layout />}>
          <Route path="/" element={<Home />} />
          <Route path="/contact" element={<ContactUs />} />
          <Route path="/not-authorized" element={<NotAuthorized />} />
          <Route path="dashboard" element={<PrivateRoute permission="dashboard">. 
          <Dashboard /></PrivateRoute>} />
          <Route path="/fot-password" element={<FotPassword />} />
          <Route path="/reset-password" element={<ResetPassword />} />
          <Route path="admin/category/create" element={<PrivateRoute 
    permission="create-category"><CreateCategory /></PrivateRoute>} />
          <Route path="admin/product/create" element={<PrivateRoute permission="create-product"><CreateProduct /></PrivateRoute>} />
          <Route path="admin/users" element={<PrivateRoute permission="view-user"><UserList /></PrivateRoute>} />
          <Route path="admin/orders" element={<PrivateRoute permission="view-order"><OrderList /></PrivateRoute>} />
          <Route path="admin/products" element={<PrivateRoute permission="view-product"><ProductList /></PrivateRoute>} />
          <Route path="admin/categories" element={<PrivateRoute permission="view-category"><CategoryList /></PrivateRoute>} />
          <Route path="admin/user/edit/:id" element={<PrivateRoute permission="update-user"><EditUser /></PrivateRoute>} />
          <Route path="admin/order/edit/:id" element={<PrivateRoute permission="update-order"><EditOrder /></PrivateRoute>} />
          <Route path="admin/category/edit/:id" element={<PrivateRoute permission="update-category"><EditCategory /></PrivateRoute>} />
          <Route path="admin/product/edit/:id" element={<PrivateRoute permission="update-product"><EditProduct /></PrivateRoute>} />
          <Route path="/admin/user/profile" element={<PrivateRoute permission="view-profile"><Profile /></PrivateRoute>} />

          <Route path="/shop" element={<Shop />} />
      </Route>
  </Routes>

); }

I’m trying to manage the security of my Laravel API application with Spatie Permissions. I’ve created a function that loads the permissions of a user, and I retrieve them on the frontend using React.js. I compare them with the permissions set in the routes, but when I debug on the frontend, I see that the permissions array is empty at first, and the route access is already blocked even though the permissions are reloaded later. However, the access remains blocked

本文标签: reactjsBlocking React Routes Before Permissions Are Reloaded from My Laravel APIStack Overflow