skip to Main Content

I’m trying to make a gate so only some users are authorized to make certain API calls, but before that I have to at least set up a gate properly which I can’t seem to do.

Here I set up the gate:

AppServiceProvider.php

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     */
    public function register(): void
    {
        //
    }

    /**
     * Bootstrap any application services.
     */
    public function boot(): void
    {
        
        
        Gate::define('alwaysTrue', function () {
            return true;
        });
    }
}

Here is the controller where I use the gate:

public function materiales_pedido($pedido_id)
{
    if (! Gate::allows('alwaysTrue')) {
        return response()->json(['message' => 'Unauthorized'], 401);
    }

    $results = [];
return $results;
}

The actual function of the controller is longer but I think its irrelevant as its just some SQL queries and it works when I remove the gate part.

Here is my api.php route

Route::get('/materiales_pedido/{pedido_id}', [PedidosConsultas::class, 'materiales_pedido']);

I’m using sanctum SPA session bassed authentication for my web app.
Even if I add ->middleware('auth:sanctum'); to the route the error continues.

This is my axios call:

const fetchMateriales = async () => {


    try {
        await axios.get('/sanctum/csrf-cookie');
        console.log(pedidoId);

        const response = await axios.get(`http://127.0.0.1:8000/api/materiales_pedido/${pedidoId}`, {
            headers: {
                'content-type': 'application/json'
            }
        });
        piezas.value = response.data;
        piezas.value.forEach(pieza => {
            pieza.cantidad_state = 'max';
        });

        console.log(piezas.value);

    } catch (error) {
        console.error('There was an error fetching the materialesPedidos:', error);
    }
};

This is my logging in authentication function:

 public function authenticate(Request $request){
        $credentials = $request->validate([
            'email' => ['required', 'email'],
            'password' => ['required'],
        ]);

        if (Auth::attempt($credentials)) {
            $user = auth()->user();
            $emailVerified = !is_null($user->email_verified_at);
            $request->session()->regenerate();

            return response()->json([
                'success' => true,
                'email_verified' => $emailVerified,
            ],200);        }

        return response()->json([
            'message' => 'The provided credentials do not match our records.',
        ], 401);
    }

Not really sure what it could be I also tried deleting all caches and chatgpt didn’t help much with this. I haven’t changed any middleware that comes with laravel 11 and cant even see them because they are hidden now in Larav11.

–IMPORTANT —
When I change the route from api.php to web.php It works IF I access that web.php route DIRECTLY through my browser but if I access that web.php route TROUGH AXIOS I still get the same 401 error,
but I’m not that experienced to know what would cause this as I’m a student trying to learn fullstack.

I would very much appreaciate your help.

I tried chaining the route from api.php to web.php but it gives mixed results depending if I access it directly or through axios.

2

Answers


  1. Chosen as BEST ANSWER

    I had the axios path wrong, on the csrf cookie I had a relative path and it had to be an absolute path and it had to be the one on my .env SANCTUM_STATEFUL_DOMAINS (so not 127.0.0.1 but localhost)

    try {
        await axios.get('http://localhost:8000/sanctum/csrf-cookie');
        console.log(pedidoId);
    
        const response = await axios.get(`http://localhost:8000/api/materiales_pedido/${pedidoId}`, {
    
            headers: {
                'content-type': 'application/json'
            }
        });
    

  2. const fetchMateriales = async () => {
        try {
            await axios.get('/sanctum/csrf-cookie');
            console.log(pedidoId);
    
            const response = await axios.get(`http://127.0.0.1:8000/api/materiales_pedido/${pedidoId}`, {
                headers: {
                    'Content-Type': 'application/json'
                },
                withCredentials: true // Add this line
            });
            
            piezas.value = response.data;
            piezas.value.forEach(pieza => {
                pieza.cantidad_state = 'max';
            });
    
            console.log(piezas.value);
    
        } catch (error) {
            console.error('There was an error fetching the materialesPedidos:', error);
        }
    };
    

    Try adding this line of code withCredentials: true. When you set withCredentials to true in Axios, it means you want to send credentials like cookies and HTTP authentication info in your requests, whether you’re sending them to the same origin or a different one. With Laravel Sanctum handling the authentication, you’ll need to include the session cookies with your API requests to make sure the user is properly authenticated.

    Axios docs – https://axios-http.com/docs/req_config

    Stackoverflow question related to this – Make Axios send cookies in its requests automatically

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search