Laravel Sanctum : blocked by CORS policy with Nuxt Auth module
Asked Answered
R

1

8

I have a Laravel website served by Valet on backend.test and a Nuxt SPA on nuxt.backend.test:3005. When I try to authenticate to Sanctum with Nuxt Auth module, I get the CORS error below:

Access to XMLHttpRequest at 'http://backend.test/login' from origin 'http://nuxt.backend.test:3005' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

How can I fix it ?

Laravel configuration

config/cors.php:

<?php

return [
    'paths' => ['*'],
    'allowed_methods' => ['*'],
    'allowed_origins' => ['*'],
    'allowed_origins_patterns' => [],
    'allowed_headers' => ['*'],
    'exposed_headers' => [],
    'max_age' => 0,
    'supports_credentials' => true,
];

routes/api.php:

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

app/Http/Kernel.php:

    protected $middlewareGroups = [
        ...
        'api' => [
            EnsureFrontendRequestsAreStateful::class,
            'throttle:60,1',
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],
    ];

.env:

SANCTUM_STATEFUL_DOMAINS="backend.test"
SESSION_DOMAIN=".backend.test"

Nuxt configuration nuxt.config.js:

export default {
  server: {
    port: '3005',
    host: 'nuxt.backend.test'
  },
  ...
  modules: [
    '@nuxtjs/axios',
    '@nuxtjs/auth-next'
  ],
  axios: {
    proxy: true
  },
  proxy: {
    '/nuxt': {
      target: 'nuxt.backend.test',
      pathRewrite: { '^/nuxt': '/' }
    }
  },
  auth: {
    redirect: {
      callback: '/auth/callback'
    },
    strategies: {
      laravelSanctum: {
        provider: 'laravel/sanctum',
        url: 'http://backend.test'
      }
    }
  },
  ...
}

pages/index.php:

<template>
  <div>
    <div>
      <pre>{{ $auth.user }}</pre>
    </div>
    <button @click="signIn()">Sign in</button>
  </div>
</template>

<script>
export default {
  methods: {
    signIn() {
      this.$auth.loginWith('laravelSanctum', {
        data: {
          email: '[email protected]',
          password: '1qaz@WSX'
        }
      })
    }
  }
}
</script>
Reductase answered 31/5, 2020 at 11:50 Comment(0)
R
4

Laravel backend and Nuxt frontend have to be under the same domain, so I finally fixed it in 3 steps:

1. Add this to /etc/hosts:

127.0.0.1   nuxt.backend.test

2. Using the beta version of @nuxt/auth:

npm remove @nuxtjs/auth
npm install @nuxtjs/auth-next @nuxtjs/axios

In nuxt.config.js, use:

  modules: [
    '@nuxtjs/axios',
    '@nuxtjs/auth-next'
  ],

3. Using the configuration below:

{
  axios: {
    proxy: true
  },
  proxy: {
    '/laravel': {
      target: 'http://backend.test',
      pathRewrite: { '^/laravel': '/' }
    }
  },
  auth: {
    strategies: {
      laravelSanctum: {
        provider: 'laravel/sanctum',
        url: '/laravel'
      }
    }
  }
}

Alternatively, replacing backend.test and nuxt.backend.test by localhost and removing Nuxt server host from nuxt.config.js and then use php artisan serve instead of Valet for Laravel is fine too.

Reductase answered 3/6, 2020 at 6:31 Comment(4)
I'm trying to make Nuxt work with Laravel's Sanctum but i have encountered few issues. I want know if you have a full working example or a code base I can use?Raeleneraf
@xperator Unfortunately not. I'm now using Laravel Passport which better fits my needs.Reductase
Ah I see.. For me I spent like 3 days to get the basic login page to work. Right now the problem is when I enable auth middleware, the app keeps redirecting to the /login page even though the this.$auth.loggedIn is true and the api/user/ from laravel side returns the right user informationRaeleneraf
I'm wondering if Laravel Passport is more or less of the same experience..? I just want a very simple classic user/pass login authentication, no fancy tokens or social network auth is neededRaeleneraf

© 2022 - 2024 — McMap. All rights reserved.