Skip to content

Instantly share code, notes, and snippets.

@balazsorban44
Last active July 5, 2023 09:36
Show Gist options
  • Star 18 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save balazsorban44/30e2267fe1105529f217acbe3763b468 to your computer and use it in GitHub Desktop.
Save balazsorban44/30e2267fe1105529f217acbe3763b468 to your computer and use it in GitHub Desktop.
NextAuth.js Auth Middleware for Next.js 12
import { getToken } from "next-auth/jwt"
import { NextResponse } from "next/server"
export async function middleware(req) {
// return early if url isn't supposed to be protected
if (!req.url.includes("/protected-url")) {
return NextResponse.next()
}
const session = await getToken({ req, secret: process.env.SECRET })
// You could also check for any property on the session object,
// like role === "admin" or name === "John Doe", etc.
if (!session) return NextResponse.redirect("/api/auth/signin")
// If user is authenticated, continue.
return NextResponse.next()
}
@balazsorban44
Copy link
Author

you will need the latest version of next-auth. As of writing 4.0.0-beta.6

@balazsorban44
Copy link
Author

you can also follow nextauthjs/next-auth#3037 for updates

@saadahmedkhan
Copy link

Thanks @balazsorban44. It works!

Quick question - is there any way we can not only validate but also extend the expiry for cookie on each request (via middleware)....just like session api does?

@balazsorban44
Copy link
Author

balazsorban44 commented Nov 7, 2021

Yes, it's planned. No ETA yet though. But any client-side request to the session endpoint (eg.: useSession, getSession) will update the expiry

@YoannBuzenet
Copy link

How can I use it with getSession() ? It returns null but I'm logged, is it normal ?

@balazsorban44
Copy link
Author

balazsorban44 commented Dec 20, 2021

getSession is tricky. It relies on dependencies that currently don't run in the Edge Runtime.

If you don't use a database session, you should be good with getToken though.

UPDATE: When I think about it, you might actually be able to use it if you pass req to it. Check the docs: https://next-auth.js.org/getting-started/client#getsession

The method that I was thinking about not working in the foreseeable future is the currently undocumented getServerSession.

Still, your best/fastest option is still getToken, as it avoids any fetch call or database access. You want your Middleware to be as quick as possible.

@oneuid
Copy link

oneuid commented Mar 4, 2022

This is not _middleware.ts error, check jose's error!

@AltumSonatur
Copy link

How can I use it with getSession() ? It returns null but I'm logged, is it normal ?

It is mentioned in next-auth docs :
Only supports the "jwt" session strategy. We need to wait until databases at the Edge become mature enough to ensure a fast experience. (If you know of an Edge-compatible database, we would like if you proposed a new Adapter)

Which means not possible to use getSession() in _middleware.ts yet.

@LuziferSenpai
Copy link

LuziferSenpai commented Apr 4, 2022

Hey, I tried to use all of this and got this Error:

firefox_GtY0hn0jb0

Code:

import { getToken } from "next-auth/jwt"
import { NextResponse } from "next/server"

export async function middleware(req) {
    const session = await getToken({ req, secret: process.env.JWT_SECRET })
    const url = req.url

    if (!session) return NextResponse.redirect("/login")

    if (url.includes("/login") && session) return NextResponse.redirect("/")

    return NextResponse.next()
}
"dependencies": {
    "@prisma/client": "^3.11.1",
    "formik": "^2.2.9",
    "next": "12.1.4",
    "next-auth": "^4.3.1",
    "react": "18.0.0",
    "react-dom": "18.0.0",
    "yup": "^0.32.11"
  },

@AltumSonatur
Copy link

There is an issue ongoing on Vercel #73

@LuziferSenpai
Copy link

I dont use Vercel, I'm on my localhost. Or is that the same?

@AltumSonatur
Copy link

Vercel is the team who is working on Next.js so it's the same

@LuziferSenpai
Copy link

Oh, thanks

@atakde
Copy link

atakde commented Apr 22, 2022

Hey, I tried to use all of this and got this Error:

firefox_GtY0hn0jb0

Code:

import { getToken } from "next-auth/jwt"
import { NextResponse } from "next/server"

export async function middleware(req) {
    const session = await getToken({ req, secret: process.env.JWT_SECRET })
    const url = req.url

    if (!session) return NextResponse.redirect("/login")

    if (url.includes("/login") && session) return NextResponse.redirect("/")

    return NextResponse.next()
}
"dependencies": {
    "@prisma/client": "^3.11.1",
    "formik": "^2.2.9",
    "next": "12.1.4",
    "next-auth": "^4.3.1",
    "react": "18.0.0",
    "react-dom": "18.0.0",
    "yup": "^0.32.11"
  },

I encouraged the same issue and solved using like that.

const { origin } = req.nextUrl;
return NextResponse.rewrite(`${origin}/login`);

@eposha
Copy link

eposha commented Jul 16, 2022

From next js 12.1.4 you need use

return NextResponse.rewrite(new URL('/', request.url));

Example:

import { NextRequest, NextResponse } from 'next/server';

export function middleware(request: NextRequest) {
  if (request.nextUrl.pathname === '/about') {
    return NextResponse.redirect(new URL('/redirected', request.url));
  }
  if (request.nextUrl.pathname === '/another') {
    return NextResponse.rewrite(new URL('/rewrite', request.url));
  }
  return NextResponse.next();
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment