nuxt-community / auth-module

Zero-boilerplate authentication support for Nuxt 2
https://auth.nuxtjs.org
MIT License
1.93k stars 925 forks source link

Laravel Sanctum login provider is just MESSED UP. #1164

Closed UsmanJavedAttari closed 3 years ago

UsmanJavedAttari commented 3 years ago

Version

"@nuxtjs/auth-next": "^5.0.0-1620155494.96c1b50", "@nuxtjs/axios": "^5.13.1", "nuxt": "^2.15.3"

Nuxt configuration

mode:

Nuxt configuration

  auth: {
    strategies: {
      laravelSanctum: {
        url: `${process.env.API_BASE_URL}/${process.env.API_PREFIX}`,
        endpoints: {
          csrf: {
            url: '/csrf-cookie'
          },
          login: {
            url: '/auth/login'
          },
          logout: {
            url: '/auth/logout'
          },
          user: {
            url: '/auth/user'
          }
        },
        //user: {
          //property: false,
        //}
      }
    },
    cookie: {
      options: {
        expires: 1
      }
    },
    localStorage: false,
    // resetOnError: true,
    redirect: {
      logout: '/sign-in',
      login: '/sign-in',
      home: '/',
      callback: '/'
    }
  },

Reproduction

Just install this module and test any laravel sanctum based API, using the above configuration.

What is expected?

The module must load the User after login, or if not atleast set is Logged In to true.

What is actually happening?

I don't know what's happening, but the user is not saving into the cookie. and whenever I refresh it just goes to login page.

Additional information

Checklist

IDK the module is broken or what is going on, I am using the simple config that should work seamlessly, but no the cookie doesn't even work. The store is activated, tried all the config from most of the issues, but doesn't work AT ALL. I tried everything which I could, but the user request is not sent. Everyone got it working, but this module doesn't work on my machine. Please help me out, already late due to this not 1 day almost 1 week. The docs are really outdated. Instead of finding the required things in docs, I am finding them in the issues. From the issues I got to know that the config which I AM USING FROM THE DOCS are outdated.

UsmanJavedAttari commented 3 years ago

Really strange behavior. Even setting the user doesn't set loggedIn to true. Cleared node_modules, .nuxt folder as well but never work.

Current code:

await this.$auth.loginWith('laravelSanctum', {
  data: this.LoginData
});

const user = await new AuthApi().checkAuth();

this.$auth.setUser(user);

And boom see, this: loggedIn: false image

This is forcing me to leave this plugin.

Even used in other projects with local, jwt schemes, but the laravelSanctum provider just messes up.

JoaoPedroAS51 commented 3 years ago

Hi @UsmanJavedAttari! I'm sure we can find out together what is going on. But first I need some more information. Can you take some screenshots of the csrf-cookie, login and user requests? Also can you show me what await new AuthApi().checkAuth() does? :)

Even setting the user doesn't set loggedIn to true.

This is an expected behaviour. We do some internal checks in order to set loggedIn state to true. If the check is failing, it means that there is something misconfigured.

UsmanJavedAttari commented 3 years ago

Hey thanks for the reply. And I am also sure we can fix it together :)

Here's what you asked for: await new AuthApi().checkAuth() it just request the user and will return user like:

{
Firstname: ....
Lastname:...,
etc:...
}

But await new AuthApi().checkAuth(), is just to call the user manually, I just removed it, and you can forget it.

So to the endpoints: the request was sent to csrf-cookie, login, just two requests. just to let you know that the login, cookies were httpOnly and was having same-site:none,secure. but I also tried setting httpOnly=false.

image

And after debugging, I got here. Here you can see const cookies =, that cookies, doesn't have the cookie sent from backend.]

image

And current config: image

JoaoPedroAS51 commented 3 years ago

I'm not sure if this is the problem, but I want you to try changing two things in your auth config.

First, set the endpoints.csrf.url to /sanctum/csrf-cookie which is the default path (unless you changed it in laravel routes). Second, set the cookie.name to XSRF-TOKEN which is the default value.

Let me know what happened! :)

UsmanJavedAttari commented 3 years ago

No, the csrf url is changed from backend, that's why I changed it, and in the screenshot above you can see, it is making a request without any issue, and after that there is login request which is also made perfectly, but still user is not logging in.

And to the cookie.name, I tried without that and it didn't work, so I assumed that may be it need to put the cookie name which is coming from backend. But it is also not working without that.

I tried bare level config as well, but it's not going to work.

And this is the cookie situation after login request:

image

UsmanJavedAttari commented 3 years ago

Also this is the domain cookie from API:

image

UsmanJavedAttari commented 3 years ago

Also tried this, with and without cookie.name:

image

JoaoPedroAS51 commented 3 years ago

Ok, what do you think about adding me on discord, so we can do some tests at real-time together Joao Pedro AS51#1284

UsmanJavedAttari commented 3 years ago

Bunch of appreciation ๐ŸŽ‰๐ŸŽ‰๐ŸŽ‰ for @JoaoPedroAS51 He really helped me on discord and his time was just priceless.

1st of all your cookie needs to have samesite=lax (which was the main issue here, was having samesite=none, secure). If you are not API developer then ask the API developer to fix it and set it to samesite=lax. If the API is on a real domain, (www.domain.com), then the cookies will not work in chrome, firefox, because of this. As the localhost is not a main, or sub-domain. So how to fix this? Here comes the 2nd point:

Use proxy, like this:

proxy: {
  '/api': { target: 'http://api.example.com', pathRewrite: {'^/api/': ''} }
}

and then in auth:

 auth: {
    strategies: {
      laravelSanctum: {
        url: '/api', //<== this is the prefix which you just made above

Now in axios:

axios: {
  proxy: true //<== this is what you need
  credentials: true //<== if your cookie is httpOnly.
}

When you will setup proxy, then request will be made from the same nuxt server URL, no matters what is your API URL, it will always request like localhost:3000/api/login, so just don't get confused.

How to setup proxy explained here, by @JoaoPedroAS51.

Read more on axios proxy here.

:warning: If you are using proxy then just never use these API_URL, API_URL_BROWSER, API_PREFIX, API_HOST and API_PORT vars in your env as they are reserved keywords by axios. Even you use the proxy, it will use the prefix and it will ruin your brain that what is happening xD

Relief!

Closing....

vwasteels commented 2 years ago

Hello @UsmanJavedAttari ! Thanks for the exta documentation on this, I followed the official doc then your thread here, but I still have issues : Laravel send the XSRF-TOKEN corectly with the first /api/sanctum/csrf-cookie call, but the token is not sent in the next calls, for example when I try a Login , I receive an error fom Laravel CSRF token mismatch , did you succeed to make this work corectly in your app ? I must admit I dont understant how the token should be persistent when the cookie is set with an other domain than localhost ... Thank you

UsmanJavedAttari commented 2 years ago

@vwasteels Hey! I am not working on that project, so can't help :(

hoopyfrood commented 1 year ago

Hello @UsmanJavedAttari !

Thanks for the exta documentation on this, I followed the official doc then your thread here, but I still have issues : Laravel send the XSRF-TOKEN corectly with the first /api/sanctum/csrf-cookie call, but the token is not sent in the next calls, for example when I try a Login , I receive an error fom Laravel CSRF token mismatch , did you succeed to make this work corectly in your app ? I must admit I dont understant how the token should be persistent when the cookie is set with an other domain than localhost ...

Thank you

Hi, experienced the same recently working on a SaaS solution, having the SESSION_DOMAIN set is optional and needn't be done.