Not able to persist data in Laravel session with a Next.js 13 api route handler

91 Views Asked by At
  1. List item

I'm using Laravel 11.x backend and my .env file is like this

...
SESSION_DRIVER=database
SESSION_LIFETIME=120
SESSION_ENCRYPT=false
SESSION_PATH=/
SESSION_DOMAIN=localhost

SANCTUM_STATEFUL_DOMAINS=localhost:3000
...

bootstrap/app.php (btw in Laravel 11 there is no kernel.php

...
     ->withRouting(
        web: __DIR__.'/../routes/web.php',
        api: __DIR__.'/../routes/api.php',
        commands: __DIR__.'/../routes/console.php',
        health: '/up',
    )
    ->withMiddleware(function (Middleware $middleware) {
        $middleware->api(prepend: [
            \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
        ]);

        $middleware->alias([
            'verified' => \App\Http\Middleware\EnsureEmailIsVerified::class,
        ]);

        //
    })
    ->withExceptions(function (Exceptions $exceptions) {
        //
    })->create();
...

cors.php (by the way in Laravel 11 cors.php is not available by default)

 'paths' => ['api/*', 'sanctum/csrf-cookie', 'login', 'logout', 'register', 'forgot-password'],

    'allowed_methods' => ['*'],

    'allowed_origins' => ['http://localhost:3000'],

    'allowed_origins_patterns' => [],

    'allowed_headers' => ['*'],

    'exposed_headers' => [],

    'max_age' => 0,

    'supports_credentials' => true,

My axios in front-end is set up like this

import Axios from 'axios'

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

export default axios;

I'm trying to make an api call to backend trying to store a cart item in a laravel session using Next.js 13 with pages directory. My Next.js file is in the pages/api directory and looks like this

import type { NextApiRequest, NextApiResponse } from "next";
import axios from '@/lib/axios'

type Data = {
  name: string;
};

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse<Data>,
) {
  const url = `${process.env.NEXT_PUBLIC_BACKEND_URL}/api/increase-cart`;
 
axios
    .post(url, req.body)
    .then(res => console.log(res.data))
    .catch(error => console.log(error))
  res.status(200).json({ name: "John Doe" });
}

It doesn't seem to be updating the same session. New session is created every time.

2

There are 2 best solutions below

0
Pranay Aryal On BEST ANSWER

I will answer my own question. This is more for my future self but will be happy if it helps anyone.

With the new Laravel 11 version,I had to move this code from api route to a ContextProvider and call the Laravel backend from there using the same axios instance described above. Somehow axios doesn't get injected with cookies using the Next.js api route handler.

1
Karl On

I got the same issue. Trying to use Server actions / Api route. Axios or Fetch. And every time I was unauthorized even if laravel sent me the 204 - noContent() from /login.

I think the only way to inject correctly session cookie is to perform the login action in client component.

And it's sad because using axios in client component doesn't allow to catch the credentials errors.