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