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()
}
@saadahmedkhan
Copy link

Thanks for the code!

I tried your snippet on Next.js 12 middleware (using Typescript) but didn't work and is giving me below error message.

TypeError: getCurves is not a function

My code is as below:

import { getToken } from "next-auth/jwt"
import { NextResponse } from "next/server"
import type { NextFetchEvent, NextRequest } from "next/server"

export async function middleware(req: NextRequest, ev: NextFetchEvent)
{
    // 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("/my-test-link")

    // If user is authenticated, continue.
    return NextResponse.next()
}

Also, Typescript is complaining on "req" parameter that the pass parameter should be of type NextApiRequest instead of NextRequest. In middleware it can't be NextApiRequest so the function getToken looks like it was made for API only.

Thanks

@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