vercel / next-learn

Learn Next.js Starter Code
https://next-learn-dashboard.vercel.sh/
MIT License
3.81k stars 1.93k forks source link

Ch 15 authentication doesn't mention that middlewares are only a first line of defense #902

Open eric-burel opened 3 weeks ago

eric-burel commented 3 weeks ago

Hi,

The authentication chapter describes using NextAuth to protect routes using a middleware.

However in currently advocated best practices, middleware authentication checks have to be understood as a first line of defense. They should be completed by authorization checks at the Data Access Layer level.

The only use case where the middleware is enough, is when setting up a paywall against static content, because an authentication check at middleware level doesn't opt into dynamic rendering, contrary to a check during data fetching. Also in the same article I've described the potential footgun of authenticating in layouts: it might be worth explaining in this tutorial maybe, so this mistakes is avoided early on.

In terms of edits, I would simply suggest adding a few lines of text to explain exactly that, that you should also check authorization in the Data Access Layer and avoid checks in layouts.

karlhorky commented 3 weeks ago

This would be great!

Would be cool to actually start by showing auth at the data layer, eg. a simple version could be a database query function like we have in our example here:

https://github.com/upleveled/next-js-example-spring-2024-atvie/blob/a337af304a4763f66e5a39cdaaf508a336017507/database/users.ts#L9-L22

export const getUser = cache(async (sessionToken: string) => {
  const [user] = await sql<Pick<User, 'username'>[]>`
    SELECT
      users.username
    FROM
      users
      INNER JOIN sessions ON (
        sessions.token = ${sessionToken}
        AND users.id = sessions.user_id
        AND expiry_timestamp > now()
      )
  `;
  return user;
});