如何在Next.js客户端页面更新数据库并防止API接口被滥用?
问题描述
我希望在用户点击特定按钮时添加一条数据库条目。目前我想到的唯一方法是创建Next API,并通过fetch调用它来更新数据库。但问题在于,任何人都可以直接访问该API端点(无需点击特定按钮)来添加数据库条目,请问该如何阻止这种情况?
对应的前端调用代码:
async function complete() { const res = await fetch(`/api/add/user?id=${id}`); const data = await res.json(); }
解决方案
下面是几种实用的拦截未授权API调用的方法:
强制用户身份校验
在API端点中加入用户权限验证,比如通过Session、JWT或者NextAuth.js实现。只有已登录且具备对应权限的用户,才能执行数据库写入操作。以NextAuth为例,API路由里可以这样处理:import { getServerSession } from "next-auth/next"; import { authOptions } from "../auth/[...nextauth]"; export default async function handler(req, res) { const session = await getServerSession(req, res, authOptions); if (!session) { return res.status(401).json({ message: "未授权访问" }); } // 执行数据库添加逻辑 res.status(200).json({ message: "操作成功" }); }启用CSRF防护
借助CSRF令牌防止跨站请求伪造,页面生成令牌后随请求携带,API端验证令牌有效性。可以用next-csrf库快速实现:
页面端调整请求:import { getCsrfToken } from "next-csrf"; async function complete() { const csrfToken = await getCsrfToken(); const res = await fetch(`/api/add/user`, { method: "POST", headers: { "X-CSRF-Token": csrfToken, "Content-Type": "application/json" }, body: JSON.stringify({ id }) }); const data = await res.json(); }API端配置验证:
import { csrf } from "next-csrf"; const csrfProtect = csrf({ secret: process.env.CSRF_SECRET, }); export default csrfProtect(async function handler(req, res) { // 执行数据库写入操作 res.status(200).json({ message: "success" }); });修改请求方法并限制访问
把原本的GET请求改成POST(或PUT),因为GET请求可以直接通过浏览器地址栏调用,而POST需要构造请求体,能提升直接调用的门槛。同时在API路由里限制仅允许指定方法访问:export default async function handler(req, res) { if (req.method !== "POST") { return res.status(405).json({ message: "仅允许POST请求" }); } // 执行数据库添加逻辑 res.status(200).json({ message: "操作成功" }); }使用一次性请求令牌
页面加载时生成唯一的一次性令牌,存储在服务器端(比如Redis)。用户点击按钮时携带该令牌,API端验证令牌存在且未被使用后,执行操作并销毁令牌。即使他人拿到接口地址,没有有效令牌也无法触发操作。
内容的提问来源于stack exchange,提问作者Mjis
相关产品推荐
相关产品推荐

