如何保护Next.js中的页面13应用路由器客户端页面和服务器端

bxfogqkk  于 2023-08-04  发布在  其他
关注(0)|答案(1)|浏览(122)

正如我在不同的地方看到的,有人使用middelware.js来保护页面(客户端和服务器端),有人使用useSession钩子来保护客户端页面,使用getServerSession来保护服务器端页面。我有一个混乱,哪一个是正确的方式和推荐的方式在nextjs 13
1.保护页面的一种方法
客户端

'use client'

import { useSession } from 'next-auth/react'
import { redirect } from 'next/navigation'

const ClientProtectPage = () => {
  const { data: session } = useSession({
    required: true,
    onUnauthenticated() {
      redirect('/signin?callbackUrl=/protected/client')
    }
  })

  return (
    <section className='py-24'>
      <div className='container'>
        <h1 className='text-2xl font-bold'>
          This is a <span className='text-emerald-500'>client-side</span>{' '}
          protected page
        </h1>
        <h2 className='mt-4 font-medium'>You are logged in as:</h2>
        <p className='mt-4'>{session?.user?.name}</p>
      </div>
    </section>
  )
}

export default ClientProtectPage



- server side protected page

 import { getServerSession } from 'next-auth/next'
        import { redirect } from 'next/navigation'
        import { authOptions } from '../../api/auth/[...nextauth]/route'
        
        const ServerProtectedPage = async () => {
          const session = await getServerSession(authOptions)
        
          if (!session) {
            redirect('/signin?callbackUrl=/protected/server')
          }
        
          return (
            <section className='py-24'>
              <div className='container'>
                <h1 className='text-2xl font-bold'>
                  This is a <span className='text-emerald-500'>server-side</span>{' '}
                  protected page
                </h1>
                <h2 className='mt-4 font-medium'>You are logged in as:</h2>
                <p className='mt-4'>{session?.user?.name}</p>
              </div>
            </section>
          )
        }
        export default ServerProtectedPage



2. second way to protect pages using middelware

    import { getToken } from "next-auth/jwt"
    import { withAuth } from "next-auth/middleware"
    import { NextResponse } from "next/server"
    
    export default withAuth(
      async function middleware(req) {
        const token = await getToken({ req })
        const isAuth = !!token
        const isAuthPage =
          req.nextUrl.pathname.startsWith("/login") ||
          req.nextUrl.pathname.startsWith("/register")
    
        if (isAuthPage) {
          if (isAuth) {
            return NextResponse.redirect(new URL("/dashboard", req.url))
          }
    
          return null
        }
    
        if (!isAuth) {
          let from = req.nextUrl.pathname;
          if (req.nextUrl.search) {
            from += req.nextUrl.search;
          }
    
          return NextResponse.redirect(
            new URL(`/login?from=${encodeURIComponent(from)}`, req.url)
          );
        }
      },
      {
        callbacks: {
          async authorized() {
            // This is a work-around for handling redirect on auth pages.
            // We return true here so that the middleware function above
            // is always called.
            return true
          },
        },
      }
    )
    
    export const config = {
      matcher: ["/dashboard/:path*", "/editor/:path*", "/login", "/register"],
    }

字符串

0ejtzxu1

0ejtzxu11#

我前几天刚进了兔子洞,想弄清楚这一点。我希望在服务器端检查auth并在客户端持久化auth,所以我跟随this tutorial学习如何在Next.js中使用服务器渲染的页面沿着Redux来从服务器到客户端共享状态。我使我的根layout.tsx文件异步加载认证数据服务器端,然后将认证数据传递给我的redux provider,以便它可以加载客户端。
我不能告诉你这是否是“正确”的实现,甚至是推荐的实现。如何管理状态有时取决于特定的用例。在我的例子中,auth对整个应用程序非常重要,我决定它应该被加载到服务器端,而不是显示一个全局加载页面。

相关问题