QwikDev / qwik

Instant-loading web apps, without effort
https://qwik.dev
MIT License
20.84k stars 1.31k forks source link

[šŸž] callbackUrl does not work with Auth.js integration #5227

Closed k-schneider closed 6 months ago

k-schneider commented 1 year ago

Which component is affected?

Qwik Runtime

Describe the bug

When specifying either a relative or absolute url (where the protocol and origin match hosted site) the callback url does not work as expected and you are always redirected to the root of the site.

Reproduction

https://stackblitz.com/edit/qwik-starter-ug5wfp

Steps to reproduce

Expected: Because I hardcoded a callbackUrl of http://localhost:5173/demo/flower you should end up on the flower demo after signing in.

Actual: You end up on the homepage.

Note: This plugin doesn't seem to like stackblitz so you'll have to do this locally

System Info

System:
  OS: Windows 10 10.0.19045
  CPU: (12) x64 AMD Ryzen 5 7600X 6-Core Processor
  Memory: 40.40 GB / 63.12 GB
Binaries:
  Node: 18.17.1 - C:\Program Files\nodejs\node.EXE
  npm: 9.6.7 - C:\Program Files\nodejs\npm.CMD
Browsers:
  Edge: Spartan (44.19041.1266.0), Chromium (117.0.2045.43)
  Internet Explorer: 11.0.19041.1566
npmPackages:
  @builder.io/qwik: ^1.2.11 => 1.2.11
  @builder.io/qwik-auth: 0.1.1 => 0.1.1
  @builder.io/qwik-city: ^1.2.11 => 1.2.11
  undici: 5.22.1 => 5.22.1
  vite: 4.4.7 => 4.4.7

Additional Information

I didn't include this in the example but I noticed that the redirect callback seems to be invoked on every request. The documentation states that it should only be called anytime the user is redirected to a callback URL so this seems incorrect.

In src/routes/plugin@auth.ts you can add this callbacks section to see how often the callback is invoked:

import { serverAuth$ } from "@builder.io/qwik-auth";
import GitHub from "@auth/core/providers/github";
import type { Provider } from "@auth/core/providers";

export const { onRequest, useAuthSession, useAuthSignin, useAuthSignout } =
  serverAuth$(({ env }) => ({
    secret: env.get("AUTH_SECRET"),
    trustHost: true,
    providers: [
      GitHub({
        clientId: env.get("GITHUB_ID")!,
        clientSecret: env.get("GITHUB_SECRET")!,
      }),
    ] as Provider[],
    callbacks: {
      redirect({ url, baseUrl }) {
        console.log("redirect", url, baseUrl);
        return url.startsWith(baseUrl)
          ? Promise.resolve(url)
          : Promise.resolve(baseUrl);
      },
    }
  }));
maiieul commented 1 year ago

Can you try removing

export const onGet: RequestHandler = async ({ cacheControl }) => {
  // Control caching for this request for best performance and to reduce hosting costs:
  // https://qwik.builder.io/docs/caching/
  cacheControl({
    // Always serve a cached response by default, up to a week stale
    staleWhileRevalidate: 60 * 60 * 24 * 7,
    // Max once every 5 seconds, revalidate on the server to get a fresh version of this page
    maxAge: 5,
  });
};

from your root layout?

I spent a week trying to make auth work with this at the root layout but this doesn't work well with browser behavior and authentication. You may be able to set cacheControl lower down the layout tree for some static authed pages with private: true, but it won't work for dynamic pages.

k-schneider commented 1 year ago

Hm, yea I can definitely see how that might cause an issue for rendering user specific content. I tried removing it and it doesn't address the callbackUrl issue though.

christian-hackyourshack commented 1 year ago

Hi Kevin!

Have you made any progress on this? I am banging my head on this since three days with no progress.

What works for me is, when I redirect to /api/auth/signin with a searchParam callbackUrl, this is written to a cookie next-auth.callback-url and used throughout the sign-in process.

But now I am providing my own signin page, in which I want to use useAuthSignin as described in the example providing a different value by providing a form field with name options.callbackUrl. This value is used in one call to the Auth.js library but never written into the cookie, so when the final redirect is done, I end up with the original callbackUrl (which is "/" by default, if you do not set it in the redirect URL).

I would be overly happy, if you could help me out of this frustration.

k-schneider commented 1 year ago

Unfortunately I didn't. When I encountered this it was for a proof of concept app built with Qwik and I've sinced moved on. Hopefully someone smarter than me can dig into it and figure out what is wrong.

carlostobon commented 1 year ago

Guys, any progress on this?

fiyazbinhasan commented 11 months ago

Thanks for the awesome library. Unfortunately I'm still facing this issue. I don't want to ditch my Qwik app for this. Any patch or temporary hack would be appreciated! Tagging @manucorporat @ulic75 as you guys have worked greatly on the library.

ulic75 commented 11 months ago

I recall looking into this in the past, but obviously didn't find anything concrete or I would have submitted a PR. I've switch from auth.js to Lucia and likely won't have the time to dig into this again, but we'll see.

lieranderl commented 6 months ago

Any progress on this?

ianlet commented 1 month ago

@PatrickJS or @wmertens could you reopen this issue as the fix from https://github.com/QwikDev/qwik/pull/6156 wasn't fully solving the problem?

I've just opened a PR in @auth/qwik to address the root cause: https://github.com/nextauthjs/next-auth/pull/11991