My biggest complaint about Next.js middleware

Поделиться
HTML-код
  • Опубликовано: 15 май 2024

Комментарии • 115

  • @nonstopper
    @nonstopper 28 дней назад +40

    This looks like hell (average next-auth experience)

  • @brad7r
    @brad7r 27 дней назад +14

    All the abstraction and inability to control your code at the right level is why I don’t bother with next anymore.

  • @Sledgeattack
    @Sledgeattack 27 дней назад +6

    From my experience there is no way to make NextAuth play nice with Edge Middleware, I have no idea why they coupled "Middleware" the programming pattern to Edge-Middleware the microservice. It feels like such a massive, hopefully unintentional, design flaw to not just have both and have them be different things.
    If I want some micro-service to run, possibly closer to the user, before my requests, have that be one thing and then you can have a function that runs before my requests on the same deployment be another thing.
    What I ended up doing with next-auth and edge middleware was just checking if the request had a next-auth cookie, that way I didn't have to include the library in the middleware microservice, but I was in the same situation were I was deploying to a company's internal Kubernetes environment and there was no reason for me to deploy my middleware as a microservice with a different runtime.

  • @ehrro
    @ehrro 28 дней назад +11

    I don't use Next Auth. I implemented my own Auth. Don't have any problem accessing the session inside middleware.

    • @WebDevCody
      @WebDevCody  28 дней назад +10

      it's not really a next-auth issue, it's that middleware doesn't allow certain node packages to work in it even though I'm running locally & on a VPS.

    • @Tanner-cz4bd
      @Tanner-cz4bd 27 дней назад +9

      Use Lucia auth or clerk

    • @aveshlutchman8573
      @aveshlutchman8573 27 дней назад +1

      ​@Tanner-cz4bd Lucia also doesn't support the session in middleware unless your db is at the edge (checked this just yesterday). I'm not sure about Clerk.

  • @DiiiaZoTe
    @DiiiaZoTe 27 дней назад +7

    This had to do with the middleware being configured to run on the edge only. I personally use Lucia auth with database sessions and use Drizzle with a MySQL database deployed on my server. The middleware does not allow me to query the DB at all to validate the session because of this edge/node issue.
    Also at 6:37, I would not recommend doing auth checks or get the user in the layout but rather in a template. The reasoning behind that is that the layout won't be triggered again on client routing between pages. A template will retrigger getting the user or validating the user to make sure it's up to date.

    • @WebDevCody
      @WebDevCody  27 дней назад

      What do you mean by template? Honestly any time data comes back from the database I run an auth check to verify the user should have access to see that data

    • @Xapyion
      @Xapyion 27 дней назад +1

      Are you talking about the template.tsx file?

    • @DiiiaZoTe
      @DiiiaZoTe 27 дней назад +2

      @@WebDevCody Correct, the template.tsx is better than layout.tsx for verifying user has access and redirect if needed. Technically, the layout should be enough but if you want to make sure that the validation happens for every route, then template.tsx should run the check from what I understand. Or do it inside each page.tsx
      Hell, I sometimes do it in all... My get user function does validation too so I wrap it with the cache function provided by react to optimize and voila. It will only process once.

  • @tmanley1985
    @tmanley1985 27 дней назад +2

    I've run into this exact thing but ended up using the jwt strategy. It honestly made me appreciate the way Laravel handles middleware so much. It's just so easy to create composable middleware that you can attach to any route or route group you want.

    • @Guergeiro
      @Guergeiro 27 дней назад +2

      For all the shit PHP gets, Laravel is actually an awesome framework and JS guys should just "copy and paste" Laravel into the JS world. The right level of abstraction that allows you to fallback to the lower level.

    • @tmanley1985
      @tmanley1985 27 дней назад +1

      @@Guergeiro I think AdonisJS is about the closest to JS you'll get in JS.

    • @tauhid97k
      @tauhid97k 26 дней назад

      @@tmanley1985 True, I love Adonis JS coming from Laravel & then Express. But people don't even know about Adonis. So underrated. Now I am trying to make authentication with next.js and Adonis. but session cookie not working with next.js for some reason. Trying to figure this out.

  • @ShivGamer
    @ShivGamer 27 дней назад +5

    I always get confused with Auth, please make a tutorial on Next auth once you figure it out😂

  • @ExileEditing
    @ExileEditing 27 дней назад +3

    You can use the middleware matcher from clerk here to run everywhere except static files to prevent that many session calls but it may still do a few more than expected

  • @HichamKazan
    @HichamKazan 27 дней назад

    you can filter your pathnames that pass through the middleware by using the exported config object
    also I tend to do the pattern you mentioned of doing ifs on the pathname for specific cases

  • @yoz0__
    @yoz0__ 27 дней назад +6

    Time to move to Remix/Nuxt.

  • @WebDevCodeCrush
    @WebDevCodeCrush 27 дней назад +1

    I’ve struggled with this as well. Not really sure what best practices might be, but at this point I just do a basic access check in middleware for admin routes or user routes to check for authentication. This at least protects my sensitive route groups, but then I do a fine grained authorization on page level for access control. Not ideal, but works.

  • @EusebioResende
    @EusebioResende 27 дней назад +2

    Smells like Vendor Lock to me.

  • @rand0mtv660
    @rand0mtv660 27 дней назад +3

    I've tried using next-auth few times and I never had a good experience. Bad docs and cryptic errors all the time. Managed to get it working, but left a bad impression. I usually work on projects where backend is separate from the Next.js app so in middleware I don't have these issues because I just ping an external API for all this session information and don't need next-auth at all really.
    Regarding 4:50 and middleware running on all requests, that's mentioned in docs and there is a "matcher" config you can specify to ignore api routes, static files etc. We developers need to learn to read docs better because I also jump into stuff immediately without actually reading few paragraphs first.
    As far as edge goes, I think Vercel just went in too deep into that with Next.js and it's causing a frustrating experience. Even they are stepping back from some of the ideas they have been pushing and admitted they were wrong, which is good.

  • @tommmywoh
    @tommmywoh 27 дней назад +1

    You could try using the neon serverless driver with the neon drizzle adapter. That's my current setup to query Supabase from Drizzle Neon in Nextjs middlewares/routes hosted on cloudflare

    • @WebDevCody
      @WebDevCody  27 дней назад +3

      I think those require your database be hosted behind a service with http access. I should be able to query my database directly like any type of backend imo

  • @iPankBMW
    @iPankBMW 27 дней назад

    It would be nice if we could put several middlewares (route based in the folders)

  • @aveshlutchman8573
    @aveshlutchman8573 27 дней назад

    I had this same issue just this week. I had hell with JWT and had to switch to Database while keeping Credentials as my default provider. I had looked into switching to Lucia and while there, I wanted to see if Lucia supported getting the session in middleware and surprisingly it also doesn't unless your DB is on the edge. When reading the reasoning behind it, it seems to be due to middleware being deployed to a Cloudfront function being the main issue and getting the session in there from a normal DB is too slow.

  • @lev1ato
    @lev1ato 27 дней назад

    I could not handle the complexity of next-auth, went with supabase auth since I was already using their db. Also Vercel is now moving from edge but we are still forced to use it on Hobby plan and in so many places not to get timeout on requests. I even asked and mentioned this in one of the PRs Leerob was in, but did not recieve the response. I think everything would be a lot easier without edge even existing, just all node runtime. But I might be wrong.

  • @jessequartey
    @jessequartey 26 дней назад

    I was facing similar issue but I didn't tinkle with the middleware setup but made some few tweaks in the next-auth configuration itself. I manually run a DB look for the jwt session to get the updated one on every request.

  • @michaelvik870
    @michaelvik870 27 дней назад

    I've had similar issues with nextjs middlewares. I find it very frustrating that the Nextjs middleware file doesnt let me do database calls. I then end up having to do a session check on each route handler that i need to protect

  • @griffadev
    @griffadev 27 дней назад +1

    Another shitty thing about next middleware is you only have one middleware file. Youd expect it to work at every point you can add a page

    • @WebDevCody
      @WebDevCody  27 дней назад +1

      Agreed. It should act like layout.tsx

  • @realbigsquid
    @realbigsquid 27 дней назад +1

    I have had the same issues with nextauth, I feel like the Middleware is more hassle than it's worth lol

  • @runners4tme
    @runners4tme 27 дней назад

    Where does layout get rendered? Is it only the client or server or both?

  • @shahzaibshahzaibkhan6480
    @shahzaibshahzaibkhan6480 27 дней назад

    Didn't use next-auth but I had to use firebase auth with Next.js Middleware, and there was a package that saved my ass called next-firebase-auth-edge, but even that was kinda complicated to set up, especially on the frontend.

  • @miro0o92
    @miro0o92 26 дней назад

    Middleware is only for edge runtime... You can not use node js apis over there. That part is really bothering since you might want to do some validations on each request etc that will be handled with node apis. A work around that i have been using since edge === browsers apis almost if you need to preform any auth checks, validation or may be a statistics gathering is to make a fetch request inside the middleware to an api endpoint created inside app/api. This way you can send the request to the endpoint preform your stuff and just a return back something like bool, null, object etc and handle it in the middleware(redirect, 404, 400 etc). Not the best way but at least it will get the job done .
    Edit: for your use case to be done in the middleware you will need a matcher (get one from the next docs) to run on a certain paths. Then get the auth cookie attach it to the fetch call and validate it over the app/api/yourendpoint . Im not 💯 sure about it tho

  • @danrot
    @danrot 25 дней назад

    Had exactly the same issue the last days. Also when you try to build the project getsession will break the compilation. Using fetch directly to get the cookie was the only way this worked for me. I‘ve also seen people just checking for session header to exist. But this seems to defeat the whole purpose of the auth, since i can send whatever i want in the session cookie -> welcome hackers btw

  • @ehsanrezaee4910
    @ehsanrezaee4910 27 дней назад

    i have the same problem with Crypto module of node js in middleware. i was using JWT package in the middleware and JWT uses crypto module of node js. so i ran into the same issue when try to use Turbopack. i opened issue 64464 and mentioned the problem. Tim Neutkins commented on the issue and fixed it. so in the canary version 14.3.0 the issue has been resolved.

  • @tevoj
    @tevoj 27 дней назад +2

    I used drizzle and I hated :(.

    • @SirMeowMeow
      @SirMeowMeow 27 дней назад

      Drizzle is extremely under-documented at the moment. I'd wait unless you like being early. I'd write a tutorial but it'll likely go out of date in a single month.

  • @darespvpmc
    @darespvpmc 27 дней назад +1

    cool video. I have a problem with the minecraft server hosting project I am trying to practice but when I run the agent it gives me an error and I can only run the client please help thanks

  • @dominuskelvin
    @dominuskelvin 24 дня назад

    Hey I’ve seen folks moves from Next to The Boring JavaScript Stack and loved it. Give it a try and let me know. We support good ol session auth out of the box

  • @lord_kh4n
    @lord_kh4n 27 дней назад

    Hey Cody, noob question here, does this mean that the middleware won't run on VPS anymore? or it's just can't run some packages on middleware?

    • @WebDevCody
      @WebDevCody  27 дней назад +1

      It just means every package you use must be edge compliant even if you don’t run in edge

    • @lord_kh4n
      @lord_kh4n 27 дней назад

      @@WebDevCody Gotcha, thank you

  • @cb73
    @cb73 27 дней назад

    Yeah it sucks. I was trying to use middleware to encrypt cookies but the crypto library doesn’t exist in the edge runtime. It does support the web api equivalents though. But do have a workaround that could work for you. I created a small api route that does the encryption for me then in the middleware I make a fetch request to get the result. You could do the same to make your database lookup.

  • @kumardeepanshu8503
    @kumardeepanshu8503 28 дней назад +2

    You and define paths where you wanted to run the middle ware, i have done that and it has reduced the amount of request made from middleware.

    • @noelpena4567
      @noelpena4567 27 дней назад

      Yea you can define the paths where you want the middleware to run. NextJS has docs on how to do this using conditional statements or using a matcher config

  • @sameerahmedk
    @sameerahmedk 26 дней назад

    Are you referring to not being able to add jwt refresh token logic in next auth? If yes, then you can actually do that.
    There are yt videos that show how, I watched them last year to understand for myself.

    • @WebDevCody
      @WebDevCody  26 дней назад +1

      Nah this was about something else

  • @soapproject
    @soapproject 14 дней назад

    Trying to use withAuth from "next-auth/middleware" with nexti18n, then find out next-auth skip my middleware callback if not authorized...

  • @kasper369
    @kasper369 27 дней назад

    What about auth callback provided by nextauth.

  • @27sosite73
    @27sosite73 25 дней назад

    this way 7:13 is better indeed
    but since you root layout is async all your app is dynamic unlike if you are making checks in the middleware

  • @lotfijbeli1471
    @lotfijbeli1471 28 дней назад

    I encountered the same error like two weeks ago, what I did was in the session (or cookies) I save as encrypted the user's role and permissions to avoid any xss stuff or in the middle stuff and accordingly I allow him to certain routes and functionalities but that demanded a lot of work in terms of if statements and defining the routes ( I had to be careful because I encountered some authorization problems ), could you give it a try and maybe you have a better approach ? Thank you

    • @carneloot
      @carneloot 28 дней назад

      That sounds like JWT with extra steps

    • @my_yt666
      @my_yt666 28 дней назад

      That's like JWT. Now you have the other problem.. invalidate the cookie on multiple devices/browsers.

  • @sasquatch_devs
    @sasquatch_devs 27 дней назад

    Had a buddy roll custom cookie session auth and has the middleware check if the user cookie auth session is legit. He ditched next-auth because of too much magic. He also uses nextjs in a bff to serverless aws lambdas running golang; dirt cheap startup stack.

  • @theScottishAlien
    @theScottishAlien 27 дней назад

    Ran into the same issue with middleware and drizzle adaptor and ended up just abandoning that strategy 🤷‍♂ but for your issue with middleware hitting every endpoint, there is a clean solution for you.
    export const config = {
    matcher: ["/((?!api|_next/static|_next/image|favicon.png).*)"],
    };
    just add a matcher that reverse matches against the kind of default next paths like _next, static, favicon etc

  • @developerpranav
    @developerpranav 27 дней назад

    that "additional plugins required to handle cloudflare: URIs" error is due to pg not working well on the edge runtime (which the next.js middleware runs on). If you move to something like neon or @vercel/pg (also works with supabase), which uses HTTP to connect to the db, it works just fine. otherwise there's a weird webpack override that you can set in next.config.js but that doesn't seem to work anymore on Next 14.1 and above?

    • @WebDevCody
      @WebDevCody  27 дней назад +1

      Yes, my complaint is i shouldn’t have to use a third party service to talk to my database. This is a dumb constraint added to a framework which feels like a vercel only feature

    • @developerpranav
      @developerpranav 27 дней назад

      @@WebDevCody agreed. wonder if setting `export const runtime = 'nodejs'` works on middleware 🤔

  • @Dom-zy1qy
    @Dom-zy1qy 27 дней назад

    You guys are still using next auth? Previous auth is where it's at.

  • @domson_0478
    @domson_0478 27 дней назад

    Middleware is only for edge runtime right now

  • @Tanner-cz4bd
    @Tanner-cz4bd 27 дней назад +2

    Try clerk or lucia auth

  • @drewhjava
    @drewhjava 27 дней назад

    I don't think layouts work for auth / authorization checks. I thought RSC's can be requested without the layout via HTTP

  • @Gangbuster74
    @Gangbuster74 26 дней назад

    I was facing same error wen I was trying to access user in events, in next auth config, if I was trying to query anything in authConfig file using drizzle it was showing same error I was using Neon tech postgres instance, and driver was pg, but changing the driver from pg to neontech which is provided with next-auth i was able to overcome this error

  • @euanmorgann
    @euanmorgann 27 дней назад

    I get that it’s a sales funnel from Vercel’s perspective, but I cannot understand why you would intentionally make the framework worse for so many people

  • @zivtamary
    @zivtamary 27 дней назад

    wdym token set for 30 days? you can manually change the cookie age on the auth config
    and everytime session is called the jwt is refreshed

    • @WebDevCody
      @WebDevCody  27 дней назад

      I honestly don’t remember what I said about 30 days. Yeah you can reduce the session max age in the next auth config.

  • @IshworGiri1999
    @IshworGiri1999 27 дней назад

    you can probably use auth() function from v5 and see if this works

  • @rishabsharma5307
    @rishabsharma5307 27 дней назад

    a noob question: why you're preferring using `database` strategy instead of `jwt`?

    • @Charizm0
      @Charizm0 27 дней назад

      Better security and control. JWT keeps the access on the user's computer making it a teeny bit inconvenient to invalidate their session if it's a rogue user. Having it on database gives him the control to invalidate their sessions whenever he wants.

  • @rakshitdubey2450
    @rakshitdubey2450 28 дней назад

    Best way to deploy on a VPS ? Node, Edge ??

    • @WebDevCody
      @WebDevCody  28 дней назад

      I use railway, people like coolify

  • @HarshDoes
    @HarshDoes 27 дней назад +1

    At this point, I just hate Next.js. Just using MERN stack does the job for me.

  • @gamingwolf3385
    @gamingwolf3385 28 дней назад

    Hello cody , i want to build more apps as junior web dev , should i use existed components , hooks , auth ... ? Or try to build them from scratch , and last time i was building react app i saw auth in it impossible to do compared to next

  • @developerpranav
    @developerpranav 27 дней назад +1

    Also relying on authorization checks in layouts isn't gonna be 100% secure. You can request an RSC payload by just adding a search param and it can return the children of layout (Page.tsx in this instance) without even executing layout.tsx
    Auth checks in page.tsx are unreliable in the same fashion.
    sources:
    ruclips.net/video/EGDD0rlBd8Q/видео.html
    ruclips.net/video/v6UvgfSIjQ0/видео.html

    • @WebDevCody
      @WebDevCody  27 дней назад +1

      I’m not sure what you mean. If you run an auth check in page.tsx, no user should be able to see the page unless they have access. Am I missing something?

    • @developerpranav
      @developerpranav 27 дней назад

      @@WebDevCody That's right, my bad. what you mentioned is most likely is the behaviour with page.tsx

  • @ericdd3329
    @ericdd3329 27 дней назад

    because nextjs doesn't give you an actual middleware, in a nodejs app you expect the middleware to be the same, simple and incredibly useful one that was using app.use in express but because of all of this caching bs they make it impossible to make dynamic responses based on data that can change, it's pretty stupid and they should give an option to disable all the caching bs with one config command.

  • @MerezinOnTheEdge
    @MerezinOnTheEdge 28 дней назад

    Isn't there a way to abstract your logic to an api endpoint and call it instead? Api calls should work just fine in the middleware

    • @WebDevCody
      @WebDevCody  28 дней назад +2

      yes, but if I'm hosting on a VPS, I shouldn't need to make a complete http request just to get info from my service that lives on the same machine. I should be able to access the db directly.

  • @buddy.abc123
    @buddy.abc123 27 дней назад

    Which is why going into 2025 we don't use JavaScript on the server

    • @WebDevCody
      @WebDevCody  27 дней назад +2

      Js on the server has nothing to do with poorly design frameworks

  • @mdtron
    @mdtron 27 дней назад

    Use Lucia Auth, always avoid next-auth

  • @googoochu3923
    @googoochu3923 28 дней назад +1

    Not gonna lie its a nextauth prob ... I got that cloudflare bug too ... Its some dbs arent compatible with edge

    • @jitx2797
      @jitx2797 28 дней назад

      But I don't understand why can't I use node stuff in middleware

    • @WebDevCody
      @WebDevCody  28 дней назад +3

      because they want you to deploy to vercel

    • @jitx2797
      @jitx2797 27 дней назад +2

      @@WebDevCody I hate that really. Like they should really separate their deployment company from a open source framework

  • @user-ik7rp8qz5g
    @user-ik7rp8qz5g 26 дней назад

    What about lucia auth?

    • @WebDevCody
      @WebDevCody  25 дней назад

      I haven’t tried it but I plan to soon

  • @justanaveragebalkan
    @justanaveragebalkan 27 дней назад +3

    If only angular existed.
    {
    path: "dashboard",
    component: DashboardComponent,
    canActivate: [() => authenticationGuard()],
    }
    My biggest gripe with anything react based is everyone tries to invent his own shitty version of what should be a standard part of the library. Angular much better, each project has a clear defined structure, yes ng-for ect ect was really annoying but it's no longer a thing, since 17 i do think it's much better than any react based "framework" out there.

    • @Yusuf-ok5rk
      @Yusuf-ok5rk 27 дней назад

      I think you are just missing Yugoslavia

    • @justanaveragebalkan
      @justanaveragebalkan 27 дней назад

      @@Yusuf-ok5rk You little sad man.

    • @Yusuf-ok5rk
      @Yusuf-ok5rk 27 дней назад

      @@justanaveragebalkan nah it was just historical joke. no offense meant.

  • @kyrregjerstad
    @kyrregjerstad 27 дней назад +2

    I had the same issue not too long ago. I ended up creating an API endpoint which takes care of the db call, and then calling that from the middleware. Not the prettiest solution, but it worked 🤷‍♂

  • @dkr91
    @dkr91 27 дней назад

    What about opennext?

    • @WebDevCody
      @WebDevCody  27 дней назад +1

      Probably the same issue, you must use edge compliant packages in middleware or next won’t build

  • @d-mathieucosyns
    @d-mathieucosyns 27 дней назад

    Your middleware file should export a config with a matcher pattern to not be called with every file request. Just like in nextjs docs.
    export const config = {
    matcher: [
    /*
    * Match all request paths except for the ones starting with:
    * - api (API routes)
    * - _next/static (static files)
    * - _next/image (image optimization files)
    * - favicon.ico (favicon file)
    */
    '/((?!api|_next/static|_next/image|favicon.ico).*)',
    ],
    }

  • @PraiseYeezus
    @PraiseYeezus 27 дней назад

    Next.js is way, way too coupled to Vercel's opinionated deployment strategies. I don't mind if a framework is opinionated; that usually just means there's a defacto "right way" to do anything you'd need to. But how on God's green earth does it make sense for a Node-based framework to ONLY allow "edge-friendly" libraries...?
    You'd think they'd have a config option to allow you to opt INTO an edge-based middleware...but since Next is designed to be deployed to Vercel I guess it's not a priority. I've been getting more and more frustrated with Next lately, I hope a new stable RSC-framework arrives soon but maybe that's unrealistic.

  • @gadgetboyplaysmc
    @gadgetboyplaysmc 27 дней назад

    I use Vike

    • @emmanuelezeagwula7436
      @emmanuelezeagwula7436 27 дней назад

      what do you to think about it ? how is the dev experience ? Can I build fullstack apps with it

    • @gadgetboyplaysmc
      @gadgetboyplaysmc 27 дней назад

      ​@@emmanuelezeagwula7436 Yes you definitely can. It definitely doesn't have the pitfalls I run into with NextJS. Since you're asking, let me give you a long ass review of it:
      Vike technically bundled by Vite so it's like A LOT faster than Next's scuffed Turbopack + Webpack bundling right now. In my personal experience. Developing feels so fast. 100% Turbopack doesn't feel like ever coming and even if it does, Vite is fast enough for me to care.
      Frontend: You can use literally any JS framework with it. Solid, Svelte, React, etc. Personally use it with Solid because Start is in RC atm.
      Backend: It's just a middleware so you can run it on any backend (Hono, H3, Fastify, etc.)
      Also heads-up, unlike Next, Vike doesn't have `/api/*` routes by default. So if you run a project with just Vike, it's technically just an html-renderer in JavaScript without the /api or GET/POST/PUT/DELETE routes. When you do attach it to your own backend, that's when you can replicate that "/api" route feature that Next has.--I personally also like this because I don't have to write my APIs in the "NextJS" paradigm. I can organize my routes and add my middlewares specific to my framework.
      Besides that, it does its job super well and there's definitely some good engineering behind it. I've used it quite extensively. There's definitely a lot more boilerplate in the beginning but it does become pretty organized in the long-run. The flexibility you can have with it is awesome.
      You really just have to try it out to know it's good. But it's definitely not for everyone, I just prefer it at this point.
      If you want comparisons: personally can compare it to SvelteKit and Remix. The file routing system is very similar to Next and SvelteKit, but more similar to SvelteKit because of `+Page` prefix and separation of server load functions into `+data`, it feels more organized. + it's actually typesafe.
      I also compare it to Remix because Remix is also taking the same approach of "just a middleware" and can run in any JS backend + Vite. But Remix is more "React", and I don't use React anymore :D

  • @skyhappy
    @skyhappy 27 дней назад

    try nuxt :s

  • @esquilo_atomico
    @esquilo_atomico 25 дней назад

    nextjs middleware experience sucks