如何在Next.js中禁止直接通过URL访问未认证的静态页面
Next.js 禁止直接输入URL访问指定静态页面的实现方案
核心实现逻辑为校验访问来源是否为站内按钮跳转,优先推荐使用路由状态校验方案,不受浏览器隐私策略限制,可靠性更高。
方案1:基于路由跳转状态校验(优先推荐)
App Router 版本实现
- 来源页面跳转时携带隐藏校验状态
'use client' import { useRouter } from 'next/navigation' export default function Home() { const router = useRouter() const handleJump = () => { // 跳转时自定义校验标记,不会暴露在URL中 router.push('/target-page', { state: { fromInternal: true } }) } return <button onClick={handleJump}>跳转目标页面</button> }
- 目标页面校验状态,非法访问直接跳转
'use client' import { useRouter } from 'next/navigation' import { useEffect } from 'react' export default function TargetPage() { const router = useRouter() useEffect(() => { // 无校验标记则判定为直接输入URL访问 if (!window.history.state?.fromInternal) { router.replace('/') // 可替换为跳转到404页面 } }, [router]) return <div>仅允许站内跳转访问的页面内容</div> }
Pages Router 版本实现
- 来源页面跳转逻辑
import { useRouter } from 'next/router' export default function Home() { const router = useRouter() const handleJump = () => { router.push({ pathname: '/target-page', state: { fromInternal: true } }) } return <button onClick={handleJump}>跳转目标页面</button> }
- 目标页面校验逻辑
import { useRouter } from 'next/router' import { useEffect } from 'react' export default function TargetPage() { const router = useRouter() useEffect(() => { if (!router.state?.fromInternal) { router.replace('/') } }, [router]) return <div>仅允许站内跳转访问的页面内容</div> }
方案2:基于referrer校验(轻量实现)
无需修改来源页面跳转逻辑,直接在目标页面校验访问来源域名,适合对安全性要求不高的场景
'use client' import { useRouter } from 'next/navigation' import { useEffect } from 'react' export default function TargetPage() { const router = useRouter() useEffect(() => { const referrer = document.referrer // 替换为你的站点域名 const isInternalJump = referrer.startsWith('https://your-domain.com') if (!isInternalJump) { router.replace('/') } }, [router]) return <div>仅允许站内跳转访问的页面内容</div> }
注意:该方案存在局限性,部分浏览器隐私策略会清空referrer,可能导致正常跳转的用户被误拦截。
内容的提问来源于stack exchange,提问作者Rafa
相关产品推荐
相关产品推荐

