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

App Router: useAuthenticatedBlitzContext with redirectAuthenticatedTo results in infinite loop #4246

Closed
tordans opened this issue Nov 2, 2023 · 4 comments · Fixed by #4257
Assignees
Labels
kind/bug Something isn't working status/done

Comments

@tordans
Copy link
Contributor

tordans commented Nov 2, 2023

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

@siddhsuresh
Copy link
Member

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

@chartgerink
Copy link

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.

@tordans
Copy link
Contributor Author

tordans commented Nov 20, 2023

@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.

@siddhsuresh
Copy link
Member

siddhsuresh commented Nov 28, 2023

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/bug Something isn't working status/done
Projects
Status: Done
Development

Successfully merging a pull request may close this issue.

4 participants