Last active
February 28, 2023 09:23
-
-
Save zsumair/906b44f08546a26048796a3c418e6604 to your computer and use it in GitHub Desktop.
JWT using middleware in nextjs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Under /lib folder of the frontend | |
import { jwtVerify, SignJWT } from 'jose' 21.6k (gzipped: 6.6k) | |
export const getJwtSecretKey () => { | |
const secret = process.env. JWT_SECRET_KEY; | |
if (!s ret || secret.length == 0) | |
throw new Error('The environment variable JWT_SECRET KEY is not set.') | |
} | |
return secret | |
} | |
export const verifyAuth = async (token) => { | |
try { | |
const verified = await jwtVerify (token, new TextEncoder ().encode (getJwtSecretKey())) | |
return verified.payload | |
} catch (error) { | |
throw new Error('Your token has expired.') | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// API route under /api folder | |
import { SignJWT } from 'jose' | |
import { nanoid } from 'nanoid' | |
import cookie from 'cookie' | |
export const getJwtSecretKey () => { | |
const secret = process.env. JWT_SECRET_KEY; | |
const authRouter = (req, res) => { | |
const { email, password } = JSON.parse(req.body); | |
if (email === process.env.ADMIN_EMAIL && password === process.env.ADMIN_PASSWORD) { | |
// user is logged in successfully | |
// return a jwt cookie to the user | |
const token = await new SignJWT({}) | |
.setProtectedHeader({ alg: 'HS256' }) | |
.setJti(nanoid()) | |
.setIssuedAt() | |
.setExpiration Time ('1m') | |
.sign(new TextEncoder ().encode (getJwtSecretKey())) | |
res.setHeader ( | |
'Set-Cookie', | |
cookie.serialize('user-token', token, { | |
httpOnly: true, | |
path: '/', | |
secure: process.env.NODE_ENV === 'production', | |
}) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { NextRequest, NextResponse } from 'next/server' | |
import {verifyAuth} from './lib/auth' | |
export async function middleware(req: NextRequest) { | |
const token = req.cookies.get('user-token')?.value | |
const verifiedToken = | |
token && | |
(await verifyAuth(token).catch((err) => { | |
console.log(err) | |
})) | |
if (req.nextUrl.pathname.startsWith('/login') && !verifiedToken | |
return | |
} | |
URL (url: string | |
if(req.url.includes('/login') && verifiedToken !== undefined): | |
return NextResponse.redirect(new URL('/dashboard', req.url)) | |
} | |
if (!verifiedToken) { | |
return NextResponse.redirect (new URL('/login', req.url)) | |
} | |
} | |
export const config = { | |
matcher: ['/dashboard', '/login'], | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment