Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

signIn with callbackUrl: undefined returns an error instead of navigating to the previous page #656

Open
clcoco opened this issue Feb 6, 2024 · 7 comments
Labels
enhancement An improvement that needs to be added p3 Minor issue provider-local An issue with the local provider

Comments

@clcoco
Copy link

clcoco commented Feb 6, 2024

Environment


  • Operating System: Darwin
  • Node Version: v20.10.0
  • Nuxt Version: 3.10.1
  • CLI Version: 3.10.0
  • Nitro Version: 2.8.1
  • Package Manager: npm@10.2.3
  • Builder: -
  • User Config: app, vite, css, postcss, runtimeConfig, imports, modules, auth, i18n
  • Runtime Modules: @sidebase/nuxt-auth@0.6.7, @pinia/nuxt@0.4.11, @nuxtjs/i18n@8.0.2
  • Build Modules: -

Reproduction

No response

Describe the bug

I'm using the local provider.
I expect the signIn function to take the user back to the pages they were trying to access while not being logged (or the index page if none was provided) but instead it returns the following error: Navigating to an external URL is not allowed by default. Use navigateTo(url, { external: true })

The code I'm using:

await signIn({
      username: user.value.email,
      password: user.value.password
    }, { callbackUrl: undefined })

More so, even if I pass external: true it returns the same error anyway

Additional context

No response

Logs

No response

@clcoco clcoco added the bug label Feb 6, 2024
@bitfactory-frank-spee
Copy link

bitfactory-frank-spee commented Feb 19, 2024

I ran into this problem also. First, I have a simple workaround implemented for now:

const { signIn } = useAuth();
const { redirectedFrom } = useRoute();

signIn(
    {
        password,
        username,
    },
    {
        callbackUrl: redirectedFrom ? redirectedFrom.fullPath : '/',
    },
);

Second, I tried to debug this error, but I could not get to the bottom of the problem in this package.

  1. I tried to use 'refresh' instead of 'local', it did not matter, although the code is different between the two!
  2. That the code is different does not matter, because they have the same default callback URL: getRequestURLWN(nuxt)
  3. If you look for that method you get this:
    export const getRequestURLWN = (nuxt: NuxtApp) => callWithNuxt(nuxt, getRequestURL)
    It calls the getRequestURL inside Nuxt. This apparantly returns an absolute URL.
  4. Vue Router gets an absolute URL to navigateTo, so it thinks it should be external, and so you need to set external: true. That is not the behaviour you want in a SPA.
    • A second workaround is to use external: true flag in the signInOptions. Important: this does not work for refresh. Because that is missing in the code there. Downside of this workaround is that the page will do a full refresh. Not so nice.

@clcoco
Copy link
Author

clcoco commented Feb 19, 2024

I ran into this problem also. First, I have a simple workaround implemented for now:

const { signIn } = useAuth();
const { redirectedFrom } = useRoute();

signIn(
    {
        password,
        username,
    },
    {
        callbackUrl: redirectedFrom ? redirectedFrom.fullPath : '/',
    },
);

It works only for internal navigation though, doesn't it? If I arrive from an external route (ie: a page refresh) it doesn't work. The redirect to the login page from the protected routes, if i'm not mistaken, is handled as external so it won't work.

   * A second workaround is to use `external: true` flag in the signInOptions. Important: this does not work for `refresh`. Because that is missing in the code there. Downside of this workaround is that the page will do a full refresh. Not so nice.

Second this, the external bool is ignored for some reason

@zoey-kaiser zoey-kaiser added p3 Minor issue enhancement An improvement that needs to be added provider-local An issue with the local provider and removed bug labels Feb 23, 2024
@Vitalii-Kh95
Copy link

I also confronted this problem but for some reason only after uaing it with signUp, like this:

async function userRegister() {
    try {
        await signUp(
            { ...register}
        );
        await signIn(
            { username: register.username, password: register.password });
    } catch (error) {
        console.log("error", error);
    }
}

this will throw an error (text bellow) even though registration and signing will be complete. But I cannot use redirect nor via callbackUrl nor via NavigateTo because code go to catch block

error message:

error Error: Navigating to an external URL is not allowed by default. Use `navigateTo(url, { external: true })`.
    at navigateTo (router.js?v=1a3ccc93:76:13)
    at signIn (useAuth.mjs?v=1a3ccc93:33:12)
    at async userRegister (signup.vue:27:9)

@bitfactory-frank-spee
Copy link

bitfactory-frank-spee commented Mar 1, 2024

@clcoco It works only for internal navigation though, doesn't it? If I arrive from an external route (ie: a page refresh) it doesn't work. The redirect to the login page from the protected routes, if i'm not mistaken, is handled as external so it won't work.

I am not sure I fully understand. The auth middleware (logged in guard) is working as intended for me. When you set this:

    globalAppMiddleware: {
        isEnabled: true,
    },

So if you come from an external route and you are not logged in you will be redirected to the login page. If you are already logged in (session in local storage / cookie / etc.) then there is no need to use signIn, the module will call getSession.

If you come from an external page directly to (or refresh on) the login page then the redirectedFrom is undefined or null. So in my workaround there is a check if it is available, if not then default the callback to the root page '/'.

@bitfactory-frank-spee
Copy link

@Vitalii-Kh95 Why can't you adjust your code to this?

async function userRegister() {
    const { redirectedFrom } = useRoute();
    
    try {
        await signUp(
            { ...register}
        );
        await signIn(
            { 
                username: register.username, 
                password: register.password,
            },
            {
                callbackUrl: redirectedFrom ? redirectedFrom.fullPath : '/',
            },
        );
    } catch (error) {
        console.log("error", error);
    }
}

So you add the second options parameter to the signIn call with the callbackUrl?

@Vitalii-Kh95
Copy link

Vitalii-Kh95 commented Mar 4, 2024

@bitfactory-frank-spee That is the problem: I did add callbackUrl and function threw an error. I simply deleted redirection and it threw the error anyway.
Now I ended by making redirect in catch block, but I don't like it.
P.S. I also call userRegister function from SignUp page so it wouldn't make sense to call const { redirectedFrom } = useRoute();, right? I am using middleware for that purpose to catch the route before going to Signin / Signup page, but I'm not sure if this is a good way since I'm a complete noob in js, vue and nuxt

@bitfactory-frank-spee
Copy link

@Vitalii-Kh95 Hmm, if it works it works 🙂. Make sure to check the documentation on local provider here: https://sidebase.io/nuxt-auth/configuration/nuxt-config and here: https://sidebase.io/nuxt-auth/application-side/session-access-and-management

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement An improvement that needs to be added p3 Minor issue provider-local An issue with the local provider
Projects
None yet
Development

No branches or pull requests

4 participants