我的 Next.js 项目中有两个页面和两个 API 路由,我想限制对其的访问。这是一个风险非常低的项目,复杂性是一个很大的缺点,所以我当前的解决方案是在这些页面的路径中放置一个不可猜测的字符串。不是这个字符串,而是这个想法:
/pages/aabbccddeeff112233/page1
/pages/aabbccddeeff112233/page2
/pages/api/aabbccddeeff112233/route1
/pages/api/aabbccddeeff112233/route2
最终我也希望能够公开代码。当然,现在我用来保护这些路由的“令牌”是 git 存储库中的一个文件夹,因此存储库需要受到保护。
所以我一直在考虑用最简单的方法(在 LOC 和设置中)来处理这个问题。没有数据库,最多有 2 个用户。 OAuth2 需要设置 GitHub 提供商并集成 NextAuth…我必须以某种方式限制可以登录允许列表上的帐户,但不签入它们。我必须设置某种登录 UI 和未经授权的帐户受保护页面的状态。对于这么小的项目来说,这感觉像是一项烦人的工作量。
所以我的问题是:
假设我能够隐藏令牌,是否有某种原因导致我当前的方法从根本上不安全?比如,应用程序的路由列表是否在客户端共享?
如果我可以保留令牌路径方法,是否有人有通过环境变量配置此令牌的示例?
我认为可能有某种原因可以通过客户端的调试器访问路由或环境变量。鉴于此,保护 Next.js 上的路由的最简单方法是什么?是否有相当于 .htpasswd 文件的文件?超级简单,但没有存储在源代码管理中,因此代码仍然可以共享?
回答我的问题:
不,依靠模糊路径来隐藏页面在 Next.js 中是行不通的。如果您访问 Next 站点并弹出调试器,您将在主线程源代码树中找到一个
_next/static/_HASH/_buildManifest.js
文件。这列出了站点上的所有路径。因此,您的路径不需要任何暴力强制或猜测,只需知道正确的位置即可。
见上文
幸运的是,保护页面和 API 路由的最简单、实际安全的方法非常简单。您所需要的只是一个环境变量和一些中间件。您创建一个中间件文件并检查搜索参数中的令牌。 (请注意,像这样在中间件中访问
searchParams
需要最新的 Next.js 13.4+,尽管在早期版本上进行更多工作也是可能的。)
/middleware.js
import { NextResponse } from 'next/server';
export async function middleware(req) {
const supplied_token = req.nextUrl.searchParams.get('token')
const valid_token = process.env.AUTH_TOKEN
if (supplied_token !== valid_token) {
const signinUrl = new URL('/', req.url)
return NextResponse.redirect(signinUrl)
}
return NextResponse.next()
}
export const config = {
matcher: ['/api/:path*', '/admin/:path*'],
}
然后生成一个令牌并将其添加到您的
.env.local
和任何云站点构建设置中,如 AUTH_TOKEN
。您还需要修改代码中对 API 方法的任何调用,以通过以下方式传递令牌:
import { useSearchParams } from 'next/navigation'
// ...
const searchParams = useSearchParams()
const token = searchParams.get('token')
fetch(`/api/my_route?token=${token}`)
就是这样!现在,当用户偶然发现受保护的页面时,他们会被重定向到
/
。当您想要访问受保护的页面时,只需在 URL 的查询字符串中提供令牌即可:
https://mysite.app/admin/delete_things?token=a1b2c3d4