blitz-js / blitz

⚡️ The Missing Fullstack Toolkit for Next.js

Home Page:https://Blitzjs.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

App Router: `useAuthenticatedBlitzContext` with `redirectAuthenticatedTo` results in infinite loop

tordans opened this issue · comments

What is the problem?

I am trying to use useAuthenticatedBlitzContext to guard an admin area so only user.role==="ADMIN" is allowed to see the pages.

  await useAuthenticatedBlitzContext({
    role: ["ADMIN"],
    redirectTo: "/login",
    redirectAuthenticatedTo: "/admin",
  })

I have a test case in this app: FixMyBerlin/blitz-test@b9c723e

  • The redirectTo works fine

  • However, the redirectAuthenticatedTo does not validate the role properly. Instead it results in an infinite loop on the page.

  • I tried working around the issue using the callback for redirectAuthenticatedTo but that does not receive any useful input as far as I can see. What is the use case for the callback, actually?

Paste all your error logs here:

Paste all relevant code snippets here:

See https://github.com/FixMyBerlin/blitz-test

  1. Checkout
  2. npx blitz db seed

Test A:
4. Create user on home page, user as ROLE=USER
5. => http://localhost:3000/regions => Redirects to login, which makes sense

Test B:
4. Create user on home page, user as ROLE=ADMIN
5. => http://localhost:3000/regions => Stays on /regions but with infinite loop

What are detailed steps to reproduce this?

Run blitz -v and paste the output here:

% npx blitz -v
Blitz version: 2.0.0-beta.35 (local)
macOS Ventura | darwin-arm64 | Node: v19.2.0


 Package manager: npm

  System:
    OS: macOS 13.6
    CPU: (8) arm64 Apple M1
    Memory: 49.58 MB / 16.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 19.2.0 - ~/.nvm/versions/node/v19.2.0/bin/node
    Yarn: Not Found
    npm: 8.19.3 - ~/.nvm/versions/node/v19.2.0/bin/npm
  npmPackages:
    @blitzjs/auth: 2.0.0-beta.35 => 2.0.0-beta.35
    @blitzjs/next: 2.0.0-beta.35 => 2.0.0-beta.35
    @blitzjs/rpc: 2.0.0-beta.35 => 2.0.0-beta.35
    @prisma/client: 5.4.2 => 5.4.2
    blitz: 2.0.0-beta.35 => 2.0.0-beta.35
    next: 13.5.4 => 13.5.4
    prisma: 5.4.2 => 5.4.2
    react: 18.2.0 => 18.2.0
    react-dom: 18.2.0 => 18.2.0
    typescript: ^5.2.2 => 5.2.2

Please include below any other applicable logs and screenshots that show your problem:

No response

Hey @tordans that's weird, I will take a look today

Thanks for reporting this issue @tordans!

I'm having a similar issue, which is causing problems in production wherever we use Page.authenticate = { role: ["ROLE"] }. It ends up looping and redirecting (if a redirect is present). It worked fine before, and I'm not sure which version introduced this regression.

@chartgerink this issue is specifically for the app router and server components.

The solution Page.authenticate = { role: "ROLE" } does not work in the server components, which is why the new hook useAuthenticatedBlitzContext was introduced (which is what this issue is about). For client components in the app router the Page.authenticate should still work – at least since #4225 was fixed.

Hey @tordans I finally took a look today, I have opened a PR to use authorise the session that we would expect when we define the roles.

Regarding the infinite loop, I feel this is an error in the code you provided.

image

So what happens here is the following:

  1. You are logged in as ADMIN
  2. The auth utility checks whether a session user exists (a rudimentary check I now agree) and redirects to the url you provides, which is the same url you are on /regions.
  3. You are continuously redirected back to /regions.

So I would think if the page is to be protected only to ADMIN users, we can do it in the following way,

await useAuthenticatedBlitzContext({
    role: ["user"],
    redirectTo: "/auth/login",
    redirectAuthenticatedTo: (ctx) => {
      const role = ctx.session.$publicData.role
      if (role === "admin") {
        return "/admin"
      }
      return "/user"
    }
  })

Adding logic to automatically handle the session role in #4257