VGabriel45
VGabriel45

Reputation: 131

NextJS delete cookies and redirect from middleware

what I want to achieve is to delete 'accessToken' and 'refreshToken' cookies if both the accessToken and refreshToken are expired and then redirect to '/login' route.

This is my code now

// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
import { verifyAccessToken, verifyRefreshToken } from './utils/checkAuth';
import jwt_decode from "jwt-decode";
import { refreshAccessToken } from './utils/refreshToken';

interface JwtPayload {
  email: string
  sub: number
  iat: number
  exp: number
}


export async function middleware(req: NextRequest) {
    const accessToken = req.cookies.get('accessToken')?.value;
    const refreshToken = req.cookies.get('refreshToken')?.value;
    
    if(accessToken && refreshToken){
      const jwtPayload: JwtPayload = jwt_decode(accessToken);

      const validToken = 
        accessToken && 
        (await verifyAccessToken(accessToken).catch((err) => {
          console.log(err); 
        }));
  
      if(req.nextUrl.pathname.startsWith('/login') && !validToken){
        return 
      }
  
      if((req.url.includes('/login') || req.url.includes('/register')) && validToken){
        return NextResponse.redirect(new URL('/login', req.url));
      }
  
      if(!validToken){
        try {
          const validRefreshToken = 
            refreshToken && 
            (await verifyRefreshToken(refreshToken).catch((err) => {
              console.log(err); 
            }));
          if(validRefreshToken){
            const newAccessToken = await refreshAccessToken(refreshToken, jwtPayload?.sub);
            console.log('GENERATED NEW ACCESS TOKEN', newAccessToken);
            // here I want to set accesToken cookie to newAccessToken
          } else {
            console.log('Refresh token expired');
            throw new Error('Refresh token expired')
          }
        } catch (error) {
          console.log('cookies should be deleted');
          return NextResponse.redirect(new URL('/login', req.url));
        }
      }
      console.log('TOKEN VALID', accessToken);
    } else {
      if(req.nextUrl.pathname.startsWith('/login')){
        return 
      } else {
        return NextResponse.redirect(new URL('/login', req.url));
      }      
    }
}

// See "Matching Paths" below to learn more
export const config = {
  matcher: ['/', '/login', '/register', '/jobs/:path*', '/profile'],
}

I found out that by doing this

const response = NextResponse.next()
response.cookies.delete('accessToken')
response.cookies.delete('refreshToken')

this will work but then for this to actually delete the cookies I need to return "response" from the middleware but I also want to redirect the user to "/login" and this does not happen if I return "response" instead of returning the "NextResponse.redirect(new URL('/login', req.url))"

How can I remove the cookies or set the cookies and then also redirect ?

Upvotes: 6

Views: 4358

Answers (1)

Wiatagan Paz
Wiatagan Paz

Reputation: 91

const response = NextResponse.redirect(new URL('/login', req.url))
response.cookies.delete('accessToken')
response.cookies.delete('refreshToken')
return response

Upvotes: 9

Related Questions