LaCoder's avatar

Laravel Sanctum Breeze with Next JS

Hello, I just installed this https://github.com/laravel/breeze-next repository and as expected everything works fine as documented. Login, Logout and registration work fine.

Now after login, I want to protect the API routes, but it throws errors as 401 when I try to access the protected route even after login.

Here is AXIOS setup as given in Repo,

import Axios from 'axios'

const axios = Axios.create({
    baseURL: process.env.NEXT_PUBLIC_BACKEND_URL,
    headers: {
        'X-Requested-With': 'XMLHttpRequest',
    },
    withCredentials: true,
})

export default axios

I just added a server call with Axios with \api\test

export async function getStaticProps() {
    const response = await axios.get(`/api/test`);
  
    return {
        props: {
            customers: response.data
        },
    }
  }

This is API in laravel.

Route::middleware(['auth:sanctum'])->get('/test', function () {
    return response()->json([
        'val' => 1,
        'msg' => 'successfully',
    ]);
});

If I remove middleware, it works fine. But when added middleware auth sanctum, it always shows 401 error.

Server Error
Error: Request failed with status code 401

This error happened while generating the page. Any console logs will be displayed in the terminal window.

So I can give authentication in SPA with sanctum?

0 likes
11 replies
drehimself's avatar

Maybe you're not importing axios from the correct place?

You should be importing it from the configured axios.js file in the project like this:

import axios from '@/lib/axios'

Check out the hooks/auth.js file as an example. They are using an extra data fetching library (swr), but you can see the raw axios calls in there. There's a call to the /api/user endpoint which is behind the auth:sanctum middleware.

Hope this helps!

LaCoder's avatar

@drehimself Hello, I did exactly the same. Actually, in the same dashboard page which gets redirected after login, I have added getStaticProp function and added Axios call there, and imported files as below,

import AppLayout from '@/components/Layouts/AppLayout'
import Head from 'next/head'
import axios from '@/lib/axios'

const Dashboard = () => {....
..
..
}

export default Dashboard

export async function getStaticProps() {
    const response = await axios.get(`/api/test`);
  
    return {
        props: {
            customers: response.data
        },
    }
  }
LaCoder's avatar

@drehimself Also, that /api/user call is not running in getStaticProp, but in the component itself. If I move this Axios call in component, it works fine, but can not use in getStaticProp or getServerProp, :-(

drehimself's avatar

@LaCoder Yeah, that was going to be my other suggestion. It looks like getStaticProps is run server-side and things on the client (like axios) might not be initialized yet.

Is there any particular reason you need to use getStaticProps? If not, you can just do your data fetching on the client side the normal way maybe using a useEffect hook.

LaCoder's avatar

@drehimself Not specific reason, but just want to render a page and fetch data on server, I first tried to follow this video https://www.youtube.com/watch?v=Urgstu-mCec&t=334s, and this repo https://github.com/themsaid/ergodnc-nextjs where he used Axios call in getStaticProp and there it worked. But he has not used this repo https://github.com/laravel/breeze-next

update....i just realised that there also all protected routes does not use getStaticProps so guess it would never be worked. So data fetching must be done in component only.

Ozan's avatar

@LaCoder Any luck with this? Without using getServerSideProps using Next.js doesn't make any sense at all, I could just build it all in Laravel. It doesn't feel good to have "loading..." every page change.

1 like
drehimself's avatar

@ozan @lacoder Bumping this thread as I'm using Next.js more and I think I found a solution.

It has to do with getServerSideProps running on the server in a Node environment so cookies aren't passed along correctly (whereas on the client, they do). Check out this thread: https://stackoverflow.com/questions/69057271/why-are-cookies-not-sent-to-the-server-via-getserversideprops-in-next-js/69058105#69058105

You have to set the cookies manually:

const response = await axios.get('/api/tweets', {
    headers: {
        origin: 'localhost', // need to pass origin to make it work
        Cookie: context.req.headers.cookie, // set cookie manually on server
    },
})

Full method here for reference:

export async function getServerSideProps(context) {
    let tweetsServer = null

    try {
        const response = await axios.get('/api/tweets', {
            headers: {
                origin: 'localhost',
                Cookie: context.req.headers.cookie,
            },
        })
        console.log(response.data)
        tweetsServer = response.data
    } catch (error) {
        console.log(error)
    }

    return {
        props: {
            tweetsServer: tweetsServer.data,
        },
    }
}
8 likes
lucasbugiolachi's avatar

@drehimself import axios from '@/lib/axios' import { z } from 'zod' import { UserSchema } from '@/schemas/User' import { cookies } from 'next/headers'

export async function getUsers() { try { const cookieStore = await cookies() const xsrfToken = cookieStore.get('XSRF-TOKEN')?.value const laravelSession = cookieStore.get('laravel_session')?.value

const cookieString = `XSRF-TOKEN=${xsrfToken}; laravel_session=${laravelSession}`

const response = await axios.get('/api/users', {
  headers: {
    Cookie: cookieString,
  },
})

const users = z.array(UserSchema).parse(response.data)
return users

} catch (error) { console.error('Error fetching users:', error) throw error } }

craftersama's avatar

I have an error with miss token when try to make login... especifically I got this message:

Request failed with status code 419

and in network I got this message:

message "CSRF token mismatch." exception "Symfony\\Component\\HttpKernel\\Exception\\HttpException" file "C:\\laragon\\www\\coanime-api\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Exceptions\\Handler.php"

If someone knows how I can avoid this type of errors I appreciate any suggest about it!

esmaeil1's avatar

@drehimself I use Lravel Santum but not token and only use session. but this method does not work.

Please or to participate in this conversation.