我有一个中间件文件,以便在我的 nextjs 14 项目中创建登录系统。我正在遵循 本指南 和 本教程
我的文件看起来像这样
import NextAuth from 'next-auth';
import { authConfig } from '@/app/auth.config';
export default NextAuth(authConfig).auth;
export const config = {
// https://nextjs.org/docs/app/building-your-application/routing/middleware#matcher
matcher: ['/((?!api|_next/static|_next/image|.*\\.png$).*)'],
};
并且运行良好!
现在......我需要更改该文件,以便我可以修改请求的标头以添加一些额外的信息并使其在整个项目中可用。
import NextAuth from 'next-auth';
import { authConfig } from '@/app/auth.config';
import { NextResponse } from "next/server";
export default NextAuth(authConfig).auth;
export const config = {
// https://nextjs.org/docs/app/building-your-application/routing/middleware#matcher
matcher: ['/((?!api|_next/static|_next/image|.*\\.png$).*)'],
};
export function middleware(request)
{
const requestHeaders = new Headers(request.headers);
const query = {};
request.nextUrl.searchParams.forEach(function(value, key)
{
query[key] = value;
});
requestHeaders.set("x-resource", request.nextUrl.pathname);
requestHeaders.set("x-query", JSON.stringify(query));
return NextResponse.next({
request: {
headers: requestHeaders,
},
});
}
问题是身份验证部分不再起作用,我的protected文件夹现在是public。难道我做错了什么?我该如何解决它?
更新1
我想这可能与我更改标头有关,但这也会导致身份验证失败
export function middleware()
{
}
因此,只要导出一个内部没有任何内容的
middleware()
函数就会破坏它。
更新2
阅读、阅读和阅读我偶然发现了这种方法
import NextAuth from 'next-auth';
import { authConfig } from '@/app/auth.config';
import { NextResponse } from "next/server";
const authProvider = NextAuth(authConfig).auth;
export const config = {
// https://nextjs.org/docs/app/building-your-application/routing/middleware#matcher
matcher: ['/((?!api|_next/static|_next/image|.*\\.png$).*)'],
};
const middleware = function(request)
{
const requestHeaders = new Headers(request.headers);
const query = {};
request.nextUrl.searchParams.forEach(function(value, key)
{
query[key] = value;
});
requestHeaders.set("x-resource", request.nextUrl.pathname.replace("/add", "").replace("/edit", ""));
requestHeaders.set("x-query", JSON.stringify(query));
return NextResponse.next({
request: {
headers: requestHeaders,
},
});
}
export default authProvider(middleware);
这种方法可行,但在登录和注销时重定向失败(它执行操作,但不重定向)
Next.js 希望您使用
export default
中间件或导出命名中间件函数 export function middleware
您不能同时导出两者。这就是为什么第一个代码片段无法按预期工作的原因。
import NextAuth from 'next-auth';
import { authConfig } from '@/app/auth.config';
import { NextResponse } from "next/server";
export const config = {
// https://nextjs.org/docs/app/building-your-application/routing/middleware#matcher
matcher: ['/((?!api|_next/static|_next/image|.*\\.png$).*)'],
};
export const middleware = NextAuth(authConfig).auth(function (request) {
// `request` now has a property `auth` containing the session
const requestHeaders = new Headers(request.headers);
const query = {};
request.nextUrl.searchParams.forEach(function (value, key) {
query[key] = value;
});
requestHeaders.set(
"x-resource",
request.nextUrl.pathname.replace("/add", "").replace("/edit", "")
);
requestHeaders.set("x-query", JSON.stringify(query));
// Auth Logic
const isProtected = true;
// this can be either
// ["/admin", "/protected", ...].includes(request.nextUrl.pathname)
// or
// ["/login", "/register", ...].includes(request.nextUrl.pathname) !== true
if (isProtected && !req.auth?.user) {
const loginUrl = new URL("/login", request.url);
// Add ?callbackUrl=/incoming-url to the /login URL
loginUrl.searchParams.set("callbackUrl", request.nextUrl.pathname);
// And redirect to the new URL
return NextResponse.redirect(loginUrl);
}
return NextResponse.next({
request: {
headers: requestHeaders,
},
});
});
如果您需要访问应用程序中的searchParams,则无需写入标头。每个
page.js
都有一个名为 searchParams
的参数
// app/edit/page.js
export default function EditPage({ searchParams }) {
const sort = searchParams.sort;
// ...
}
或通过客户端组件中的
useSearchParams
"use client";
import {useSearchParams} from "next/navigation";
export function MyComponent() {
const searchParams = useSearchParams();
const sort = searchParams.get("sort")
}