You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Next.js前端隐藏/保护API路由?

隐藏Next.js /api路由,禁止前端直接访问的方案

1. 限制请求来源(拦截非本站发起的请求)

在/api路由的处理函数中,通过验证请求的Origin或Referer头,只允许来自你自身前端域名的请求访问:

export default function handler(req, res) {
  const allowedOrigin = process.env.NEXT_PUBLIC_APP_URL; // 替换为你的前端域名,如https://your-app.com
  const origin = req.headers.origin || req.headers.referer;

  // 验证请求来源是否合法
  if (!origin || !origin.startsWith(allowedOrigin)) {
    return res.status(403).json({ message: "禁止直接访问API" });
  }

  // 正常业务逻辑
  res.status(200).json({ data: "安全返回内容" });
}

注意:这种方法能挡住普通用户直接输入URL访问,但Origin/Referer可被伪造,适合基础防护场景。

2. 改用服务器端专属逻辑(完全不暴露/api端点)

如果你的API仅用于Next.js内部(比如服务器组件、getServerSideProps、其他服务调用),可以把业务逻辑抽离到服务器端专属模块,彻底不创建/api路由:

// lib/api/user.js(仅服务器端可访问)
export async function getUserData(userId) {
  // 直接操作数据库或第三方服务
  return await db.user.findUnique({ where: { id: userId } });
}

在服务器组件中直接调用:

// app/user/[id]/page.js
import { getUserData } from '@/lib/api/user';

export default async function UserPage({ params }) {
  const user = await getUserData(params.id);
  return <div>{user.name}</div>;
}

这种方式完全不会对外暴露API端点,是最安全的方案。

3. 添加API密钥验证

在请求头中加入自定义密钥,仅允许携带有效密钥的请求访问API:

// /api/data.js
export default function handler(req, res) {
  const apiKey = req.headers['x-api-key'];
  const validKey = process.env.API_SECRET_KEY; // 从环境变量读取密钥

  if (!apiKey || apiKey !== validKey) {
    return res.status(401).json({ message: "无效的API密钥" });
  }

  // 业务逻辑处理
  res.status(200).json({ data: "安全数据" });
}

前端调用时在请求头中携带密钥:

async function fetchData() {
  const res = await fetch('/api/data', {
    headers: {
      'x-api-key': process.env.NEXT_PUBLIC_API_KEY
    }
  });
  const data = await res.json();
}

注意:前端暴露密钥存在被窃取风险,此方案更适合服务器端之间的调用。

4. 用Middleware全局拦截/api请求

在项目根目录创建middleware.js,统一拦截所有/api开头的请求,验证通过才允许访问:

import { NextResponse } from 'next/server';

export function middleware(request) {
  const allowedOrigin = process.env.NEXT_PUBLIC_APP_URL;
  const origin = request.headers.get('origin') || request.headers.get('referer');

  if (request.nextUrl.pathname.startsWith('/api') && (!origin || !origin.startsWith(allowedOrigin))) {
    return new NextResponse(JSON.stringify({ message: "禁止直接访问" }), {
      status: 403,
      headers: { 'Content-Type': 'application/json' }
    });
  }

  return NextResponse.next();
}

export const config = {
  matcher: '/api/:path*', // 匹配所有/api路由
};

这种方式无需在每个/api路由中单独写验证逻辑,实现全局统一防护。

内容的提问来源于stack exchange,提问作者Raghav Patel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 17:22:46