0

I'm using Laravel Sanctum on a LAMP Stack. I have my frontend react app pointed to /var/www/app.example.com and my backend Laravel pointed to /var/www/appapi.example.com on the same server. Both load fine.

I am currently building off of this tutorial - https://dev.to/dog_smile_factory/series/5857

If you open the dev tools and follow its workflow, you can register for a new user, be logged in, and then it will auto attempt to hit the api/users route - which always returns unauthenticated.

Even with everything as wide open as I can figure, I'm not getting through - here is what I have:

CORS.php

'paths' => ['api/*', 'sanctum/csrf-cookie', '*'],

'allowed_methods' => ['*'],

'allowed_origins' => ['*'],

'allowed_origins_patterns' => [],

'allowed_headers' => ['*'],

'exposed_headers' => [],

'max_age' => 0,

'supports_credentials' => true,

.env

APP_NAME=Laravel
APP_ENV=local
APP_KEY=base64:2tD+oAGu+NOPE+NOPE+NOPE+gq9brRpfuKCL+t4M=
APP_DEBUG=true
APP_URL=appapi.example.com

LOG_CHANNEL=stack
LOG_LEVEL=debug

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=apppue
DB_USERNAME=root
DB_PASSWORD=NopeNopeNope

BROADCAST_DRIVER=log
CACHE_DRIVER=file
QUEUE_CONNECTION=sync
SESSION_DRIVER=cookie
SESSION_LIFETIME=120

MEMCACHED_HOST=127.0.0.1

REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379

SESSION_DOMAIN=.example.com
SANCTUM_STATEFUL_DOMAINS=.example.com

kernel.php

'api' => [
    EnsureFrontendRequestsAreStateful::class,
    'throttle:60,1',
    \Illuminate\Routing\Middleware\SubstituteBindings::class,
],

api.php

Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
    return $request->user();
});

Route::post('/login', 'UserController@login');
Route::post('/register', 'UserController@register');
Route::get('/logout', 'UserController@logout');

On my React App

All axios requests look like this (withCredentials = true):

axios.defaults.withCredentials = true;
// CSRF COOKIE
axios.get(hostName + "sanctum/csrf-cookie").then(
  (response) => {
    //console.log(response);
    // SIGNUP / REGISTER
    axios
      .post(hostName + "api/register", {
        name: userNameInput,
        email: userEmail,
        password: userPassword,
      })
      .then(
        (response) => {
          //console.log(response);
          // GET USER
          axios.get(hostName + "api/user").then(
            (response) => {
              //console.log(response);
              setUserId(response.data.id);
              setUserName(response.data.name);
              setErrorMessage("");
              setAuthStatus(LOGGED_IN);
            },
            // GET USER ERROR
            (error) => {
              setErrorMessage("Could not complete the sign up");
            }
          );
        },
        // SIGNUP ERROR
        (error) => {
          if (error.response.data.errors.name) {
            setErrorMessage(error.response.data.errors.name[0]);
          } else if (error.response.data.errors.email) {
            setErrorMessage(error.response.data.errors.email[0]);
          } else if (error.response.data.errors.password) {
            setErrorMessage(error.response.data.errors.password[0]);
          } else if (error.response.data.message) {
            setErrorMessage(error.response.data.message);
          } else {
            setErrorMessage("Could not complete the sign up");
          }
        }
      );
  },
  // COOKIE ERROR
  (error) => {
    setErrorMessage("Could not complete the sign up");
  }
);

};

The x-xrfs-token is getting saved correctly from what I can tell and passed in with each of the requests. Maybe I'm misunderstanding something about this though and that's why I can't hit my authenticated route api/users.

I've been working on this for 4 days following several tutorials, laravel docs, and scavaging the web - somehow I'm still missing something. Most tutorials are doing this on localhost and I'm configuring it on a LAMP stack. It's the only piece I see that is different. What am I doing wrong?

sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
Jay
  • 566
  • 6
  • 18

1 Answers1

1

After days of testing, reading documentation, and other tutorials (including the most helpful one - (https://laravel-news.com/using-sanctum-to-authenticate-a-react-spa))

I figured out the problem.

SANCTUM_STATEFUL_DOMAINS=.example.com

I was completely confused about what to put here, and testing it and proving it was correct/incorrect was very difficult. Even editing the vendor files, I couldn't get it to return anything to my frontend app (app.example.com). All the tutorials online were developing using localhost:3000 and localhost:8000. When building this on a real server, however, those tuts proved less than sufficient in this area - so hopefully this helps someone else!

THE ANSWER FOR ME: If you're able to log in to your account BUT NOT able to get passed any auth:sanctum middleware protected routes AND you're getting the XSRF-TOKEN cookie and laravel_session cookie (check your application/storage developer tab (chrome/firefox respectively)) then the problem lies in what you have listed in your SANCTUM_STATEFUL_DOMAINS. I tried putting https://app.example.com, http://app.example.com, .example.com, example.com - all seemed to fail. So what worked?

app.example.com

Lose the https, http, maybe even www (honestly I didn't test this one), but make sure you have the subdomain listed!

Jay
  • 566
  • 6
  • 18