Nextjs Middleware rewrite routes and won't redirect even when user is logged in

1.1k Views Asked by At

I am facing an issue in nextjs middleware I am building a ecommerce app that has three actors [admin , customer , vendor] in middleware i have a function that decode the token from header cookies and then returns the data containing user email , id etc everything work good in logically routes , auth is perfect problem is , when user click on path like 'customer/cart or account' i want to validate if he is actually a registered user or not and if not middleware redirect it to auth/login the problem is it rewrite the url of auth/login to customer/account so after login where i have a code like router.push('/customer/account') doesn't seems to works its creating a complete mess in the rewrite is there any way preventing a rewrite and can work with redirect???

middleware.ts

import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
import { getDataFromToken } from './helpers/auth'



export async function middleware(request: NextRequest) {
    const path = request.nextUrl.pathname

    const token = request.cookies.get('token')?.value || ''

    const userData = await getDataFromToken(request)
    console.log(" ~ file: middleware.ts:13 ~ middleware ~ userData:", userData)


    // admin validation
    const isAdminPath = path.startsWith('/admin');

    if (isAdminPath && (token === '' || userData?.role !== 'admin')) {
        return NextResponse.rewrite(new URL('/auth/login', request.url))
    }

    // customer validation
    const isUserAccount = path.startsWith('/customer/account');
    const isUserCart = path.startsWith('/customer/cart');

    if (token && token !== '' && userData?.role === 'customer') {
        return NextResponse.rewrite(new URL('/customer/account', request.url))
    }



    if ((isUserAccount || isUserCart) && (token === '' || userData?.role !== 'customer')) {
        return NextResponse.rewrite(new URL('/auth/login', request.url))
    }


}


export const config = {
    matcher: [
        '/customer/account', 
        '/customer/cart',
        '/admin',
    ],
}
2

There are 2 best solutions below

0
On BEST ANSWER

Fixed it

Example

if (request.nextUrl.pathname.startsWith('/admin'))
    {
        if (token === '' || userData === null || userData?.role !== 'admin') {
            return NextResponse.redirect(new URL('/auth/login', request.url))
        }
    }


    if (request.nextUrl.pathname === '/auth/login' || request.nextUrl.pathname === '/auth/register')
    {
        if ((token !== '' || !token) && userData !== null && userData?.role === 'admin') {
            return NextResponse.redirect(new URL('/admin/home', request.url))
        }
    }

We can use Redirect simply by replacing Rewrite . this fix the issue for me

0
On

In addition to @Abdullah's answer, to have all pages authorized by next auth, you just create your middleware

import type { NextRequest } from 'next/server'
import { NextResponse } from 'next/server'

export function middleware(request: NextRequest) {
        return NextResponse.redirect(new URL('/auth/login', request.url))
}

Unfortunately, even with the absolute URL, it still causes the redirected(login) page to break; it turns out that explicitly defining the secured pages fixes the issue

import type { NextRequest } from 'next/server'
import { NextResponse } from 'next/server'

export function middleware(request: NextRequest) {
        return NextResponse.redirect(new URL('/auth/login', request.url))
}

export const config = { matcher: ["/profile"] };