Confused on Next.js middleware recommendation
Setting up authentication for an internal tool and want to set up the middleware to perform authentication checks on pretty much every route. I'm wondering if anyone can help me understand the reasoning behind this recommendation in the docs (https://www.better-auth.com/docs/integrations/next#middleware)
"In Next.js middleware, it's recommended to only check for the existence of a session cookie to handle redirection. To avoid blocking requests by making API or database calls."
Couple of other questions:
1. Am I right to assume that solely checking for the existence of a session cookie is not secure?
2. In addition to checking for the existence of a session cookie, I should also be checking the session using getSession right?
3. I'm wondering whether I should be doing the getSession check in the middleware, at the beginning of every protected route, or both. 4. Is it possible to test using secure cookies locally? LLM noted that setting up a local HTTPS environment with a self-signed certificate is the best practice, any recommendations for doing so? Thanks in advance!
3. I'm wondering whether I should be doing the getSession check in the middleware, at the beginning of every protected route, or both. 4. Is it possible to test using secure cookies locally? LLM noted that setting up a local HTTPS environment with a self-signed certificate is the best practice, any recommendations for doing so? Thanks in advance!
Next.js integration | Better Auth
Integrate Better Auth with Next.js.
Solution:Jump to solution
Yea the best practice is to optimistically check for the presence of cookie in the middleware, then check getSession on a route if you need to protect that route server side. Using getSession on a page requires headers which will opt your page out of static rendering and turn it into a serverless invocation instead of serving it from edge cache. For this reason, some projects may just use Cookie check in middleware and then a client side auth check using useSession instead of getSession server side. I personally do this to reduce cost, since serving a static page from edge cache is much faster and cheaper.
Middleware is not meant for blocking network requests, it slows down your site. Next.js suggests using non-blocking optimistic checks in middleware. The optimistic check pretty much says - if there isn't a cookie, then we can skip loading that route altogether. If there is a cookie, render the route. Then the route is a serverless invocation where you can check for getSession and use Suspense to render a loading state. Or you can have a static page with a client side check for isPending on useSession to render your loading state...
7 Replies
Solution
Yea the best practice is to optimistically check for the presence of cookie in the middleware, then check getSession on a route if you need to protect that route server side. Using getSession on a page requires headers which will opt your page out of static rendering and turn it into a serverless invocation instead of serving it from edge cache. For this reason, some projects may just use Cookie check in middleware and then a client side auth check using useSession instead of getSession server side. I personally do this to reduce cost, since serving a static page from edge cache is much faster and cheaper.
Middleware is not meant for blocking network requests, it slows down your site. Next.js suggests using non-blocking optimistic checks in middleware. The optimistic check pretty much says - if there isn't a cookie, then we can skip loading that route altogether. If there is a cookie, render the route. Then the route is a serverless invocation where you can check for getSession and use Suspense to render a loading state. Or you can have a static page with a client side check for isPending on useSession to render your loading state
If you don't care about optimal speed, performance, scaling or cost, and simply prefer a simpler DX with those trade offs, then it's ok to use getSession in middleware. There was a bug in Next.js middleware not too long ago that led to some issues in sites that did auth checks in middleware though. They patched it, and they've always said to do optimistic cookie checks only in middleware. But if you need ultimate security (Banking, etc) I definitely suggest using a getSession check in each SSR page.
Delba
YouTube
Next.js: Authentication (Best Practices for Server Components, Acti...
Best practices for authentication in Modern Next.js and React: Server Components, Server Actions, Middleware.
Docs: https://rc.nextjs.org/docs/app/building-your-application/authentication
Code: https://github.com/vercel-labs/app-router-auth
00:00 Intro
00:25 Forms and Server Actions
00:51 Form validation
01:06 useActionState
01:45 Creating a u...
Thanks so much this clears things up a lot, the trade offs you mentioned likely aren't that much of a concern given the traffic will be extremely low but regardless doing getSession check in each SSR page seems like the better option. Still need to do a deep dive on server components and SSR so appreciate the video gonna check it out now. Thanks a bunch!
I guess to be clear, for highest security, use getSession on each route.
For fastest performance and lowest cost, use useSession on the client side and check for session presence to conditionally render protected components.
The cookie check in middleware is actually the most optional check, this can reduce cost and speed up the site by skipping unnecessary renders
If you do go the SSR getSession route, I definitely recommend using Suspense boundaries or loading.tsx with Skeletons so the page renders immediately when it's visited
Got it, will look into these options. Ya I was planning on setting up loading.tsx files for each route as well.
better-auth-ui looks super nice btw gonna check this out and maybe integrate into my project
Yea I have a big update with Organization features coming later this weekend