Login using Axios and API Platform (Symfony)

Recently, I wanted to implement a simple login form in my Vue.js application, using a JSON Login.

Normally, this is pretty easy and straightforward: Implement the login funtionality as described in the link above, send a POST request to /login with email and password and everything else (save the Session Cookie and send it on every following request) is handled automatically.

But this works only if your frontend (Vue) and your backend (Symfony) are on the exact same domain (local.dev and api.local.dev are NOT the same domain). Yes, the login may be successful, a session was created and even a Set-Cookie header with PHPSESSID was returned, but when you try to send a second request (maybe a GET /currentUser), you will see, that you are not logged in anymore. But why?

You need to set withCredentials to true in your XMLHttpRequest. The important part is:

XMLHttpRequest from a different domain cannot set cookie values for their own domain unless withCredentials is set to true before making the request.

So, even when there is a Set-Cookie header in your response, your browser will not save the cookie. To fix this, you should add

{
    // ...
    withCredentials: true,
    // ...
}

to your global axios configuration. If you are using NuxtJS, you have to create plugins/axiosCredentials.js:

export default function ({ $axios }) {
  $axios.onRequest((config) => {
    config.withCredentials = true

    return config
  })
}

and add it to the plugins section of your nuxt.config.js

export default {
  // ...
  plugins: ['@/plugins/axiosCredentials.js'],
  // ...
}

Then second, easy, part is a little modification in your Symfony configuration:

nelmio_cors:
    defaults:
        allow_credentials: true 

Add allow_credentials: true to your config/packages/nelmio_cors.yaml. Leave everything else as it. Without this configuration, the answer to your login attempt will be

Access to XMLHttpRequest at 'http://local.dev:8000/login' from origin 'http://local.dev' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.

Schreibe einen Kommentar