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

NextJS如何禁止指定目录访问并仅向已登录用户提供图片服务

NextJS 实现私有图片资源访问方案

第一步:调整敏感图片存放位置

NextJS 中/public目录下的所有资源默认会作为静态资源公开访问,无法直接通过业务逻辑禁止访问,因此优先建议将需要鉴权的图片移出/public目录,你可以在项目根目录新建一个非公开的存放目录,例如private_images/,该目录不会被直接对外暴露,从根源上避免用户直接访问到原始图片。

第二步:拦截公开目录的非法访问

如果你确实需要保留图片在/public/images下,可以通过根目录的middleware.ts匹配对应路径的请求,直接拦截未登录用户的访问:

import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export function middleware(request: NextRequest) {
  // 匹配所有/public/images下的请求
  if (request.nextUrl.pathname.startsWith('/images/')) {
    // 这里替换为你自己的登录态校验逻辑,例如校验cookie里的token、session等
    const isLogin = request.cookies.has('user_token')
    if (!isLogin) {
      return new NextResponse('禁止访问', { status: 403 })
    }
  }
}

export const config = {
  matcher: '/images/:path*',
}

第三步:完善带鉴权的图片API路由

Pages Router 版本(适配你现有的写法)

你现有的API路由逻辑可以补充鉴权逻辑,建议做成动态路由适配不同图片,示例如下:

// pages/api/image/[name].js
export default async function handler(req, res) {
  // 先做登录态校验,替换为你自己的业务校验逻辑
  const isLogin = req.cookies.user_token
  if (!isLogin) {
    return res.status(403).send('禁止访问')
  }

  const { name } = req.query
  res.setHeader('Content-Type', 'image/jpg')
  // 可以读取本地private_images下的文件,或者请求内部存储的图片资源
  const imageBuffer = await (await fetch(`http://内部存储地址/images/${name}.jpg`)).body
  res.send(imageBuffer)
}

对应Image组件用法:

<Image src={`/api/image/logo`} alt="Logo" width={720} height={160} />

App Router 版本

如果使用NextJS13+的App Router,可以用Route Handler实现相同逻辑:

// app/api/image/[name]/route.ts
import { NextResponse } from 'next/server'
import { cookies } from 'next/headers'

export async function GET(request: Request, { params }: { params: { name: string } }) {
  const cookieStore = cookies()
  const isLogin = cookieStore.has('user_token')
  if (!isLogin) {
    return new NextResponse('禁止访问', { status: 403 })
  }

  const res = await fetch(`http://内部存储地址/images/${params.name}.jpg`)
  const imageBuffer = await res.arrayBuffer()

  return new NextResponse(imageBuffer, {
    headers: {
      'Content-Type': 'image/jpg',
    },
  })
}

额外说明

  • 所有私有图片访问都走封装的API路由即可实现和PHP相同的鉴权效果,不要将私有图片的实际存储地址对外暴露
  • 如果使用云存储存储图片,可以配合生成带过期时间的签名URL,安全性更高

内容的提问来源于stack exchange,提问作者Petr Marek

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 20:54:04