防止经过身份验证的用户使用下一个身份验证中间件访问自定义登录页面

问题描述 投票:0回答:3

我们目前正在使用

next-auth
开发 NextJS 13 的应用程序,到目前为止一切都很好。我们的应用程序使用带有
CredentialsProvider
的自定义登录页面,并且我们使用 next-auth 中间件来保护我们的路由。如果我们的用户已经通过身份验证,我们希望阻止他们访问
/login
。我们成功地在客户端中通过
useSession()
实现了这一点,但我们正在寻找一种方法来在中间件中实现此逻辑。使用当前的
next-auth
中间件实现可以实现这一点吗?以下是我们当前的中间件和路由配置。谢谢你。

//middleware.ts
import withAuth from 'next-auth/middleware';

export default withAuth({
  pages: {
    signIn: `/login`,
  },
});

//route.ts
import NextAuth from 'next-auth';
import CredentialsProvider from 'next-auth/providers/credentials';

const handler = NextAuth({
  pages: {
    signIn: `/login`,
  },
  session: {
    strategy: 'jwt',
  },
  providers: [
    CredentialsProvider({
      name: 'Credentials',
      credentials: {
        username: { label: 'Username', type: 'text' },
        password: { label: 'Password', type: 'password' },
      },
      async authorize(credentials, req) {
        //auth logic here
      },
    }),
  ],
});

export { handler as GET, handler as POST };
reactjs authentication next.js middleware next-auth
3个回答
10
投票

这对我们有用。也归功于@Yilmaz,这是基于他的回答。

import { getToken } from 'next-auth/jwt';
import { withAuth } from 'next-auth/middleware';
import { NextFetchEvent, NextRequest, NextResponse } from 'next/server';

export default async function middleware(req: NextRequest, event: NextFetchEvent) {
  const token = await getToken({ req });
  const isAuthenticated = !!token;

  if (req.nextUrl.pathname.startsWith('/login') && isAuthenticated) {
    return NextResponse.redirect(new URL('/dashboard', req.url));
  }

  const authMiddleware = await withAuth({
    pages: {
      signIn: `/login`,
    },
  });

  // @ts-expect-error
  return authMiddleware(req, event);
}

6
投票
import { getToken } from "next-auth/jwt";
import { withAuth } from "next-auth/middleware";
import { NextResponse } from "next/server";

// For the time being, the withAuth middleware only supports "jwt" as session strategy.
export default withAuth(
  async function middleware(req) {
    const token = await getToken({ req });
    // if token exists, !!token will be true
    const isAuthenticated = !!token;
   
    // first, check if the current path is login page
    if (req.nextUrl.pathname.startsWith("/login")) {
      // I am in "login" page now  I check if the user is authenticated or not
      if (isAuthenticated) {
         // If I get here it means user is on "login" page and it is authenticated. then redirect it to whatever url
        return NextResponse.redirect(new URL("/whatever", req.url));
      }
     
    }
);

// specify on which routes you want to run the middleware
export const config = {
  matcher: ["/", "/login""],
};

0
投票

使用 [电子邮件受保护][电子邮件受保护] @alexortizl 的解决方案仍然有效。

这是它的简化 js 版本。

import { getToken } from 'next-auth/jwt';
import { withAuth } from 'next-auth/middleware';
import { NextResponse } from 'next/server';

export default async function middleware(req) {
     const token = await getToken({ req });
     const isAuthenticated = !!token;

     if (req.nextUrl.pathname.startsWith('/auth/signin') && isAuthenticated) {
          return NextResponse.redirect(new URL('/protected/profile', req.url));
     }

     return await withAuth(req, {
          pages: {
               signIn: '/auth/signin',
          },
     });
}
© www.soinside.com 2019 - 2024. All rights reserved.