在 Next.js 13.4 中间件中设置烹饪

问题描述 投票:0回答:1

我在中间件函数中写入 cookie 时遇到问题。

我有多个中间件功能链接起来:

import { chain } from '@/middlewares/chain';
import { intlMiddleware } from '@/middlewares/intl_middleware';
import { authMiddleware } from '@/middlewares/auth_middleware';
import { localUrlMiddleware } from '@/middlewares/localURL_middleware';

export default chain([
    localUrlMiddleware,
    // authMiddleware,
    intlMiddleware,
    // add more middlewares here
])

export const config = {
    matcher: ['/((?!api|_next/static|_next/image|favicon.ico|images/).*)']
}

我遇到的问题是第一个:

import { NextResponse } from 'next/server'
import type { NextFetchEvent, NextMiddleware, NextRequest } from 'next/server'
import { Locale, i18nConfig } from '@/lib/translations/i18n.config'
import { match as matchLocale } from '@formatjs/intl-localematcher'
import Negotiator from 'negotiator'

function getLocale(request: NextRequest): string {
    const cookieStore = request.cookies
    console.log('Cookies:', cookieStore);

    const localeCookie = cookieStore.get('NEXT_LOCALE')?.toString();
    if (localeCookie) {
        console.log('Locale cookie:', localeCookie);
        return localeCookie
    }

    const negotiatorHeaders: Record<string, string> = {}
    request.headers.forEach((value, key) => (negotiatorHeaders[key] = value))
    console.log('Negotiator headers:', negotiatorHeaders);

    // @ts-ignore locales are readonly
    const locales: string[] = i18nConfig.locales
    const languages = new Negotiator({ headers: negotiatorHeaders }).languages()
    console.log('Preferred languages:', languages);


    const locale = matchLocale(languages, locales, i18nConfig.defaultLocale)
    console.log('Matched locale:', locale);
    cookieStore.set({
        name: 'NEXT_LOCALE',
        value: locale,
    })
    return locale
}

export function localUrlMiddleware(nextMiddleware: NextMiddleware) {
    return async (request: NextRequest, event: NextFetchEvent) => {
        console.log('localUrl middleware called!');
        const pathname = request.nextUrl.pathname
        console.log('pathname:', pathname)

        const pathnameIsMissingLocale = i18nConfig.locales.every(
            locale => !pathname.startsWith(`/${locale}/`) && pathname !== `/${locale}`
        )

        // Redirect if there is no locale
        if (pathnameIsMissingLocale) {
            const locale = getLocale(request)
            console.log('missing locale in url, attributing one:', locale);

            return NextResponse.redirect(
                new URL(
                    `/${locale}${pathname.startsWith('/') ? '' : '/'}${pathname}`,
                    request.url
                )
            )
        }
        return nextMiddleware(request, event);
    }
}

getLocale 函数查找 NEXT_LOCALE cookie,如果没有,则设置一个新的。 然而,cookie 永远不会被写下来!

这是

的输出
    const cookieStore = request.cookies
    console.log('Cookies:', cookieStore);

当用户注销时,我有:

Cookies: RequestCookies {}

登录时间:

Cookies: RequestCookies {"next-auth.csrf-token":{"name":"next-auth.csrf-token","value":"1e7c35197cf1706cdcad5b55529c4712af49fb719893fe744bef32523c0997a5|034e93b1da0508b7543836bdb078e0655c2cca1ef5624145607f5f648b5c8813"},"next-auth.callback-url":{"name":"next-auth.callback-url","value":"http://localhost:3000/"},"next-auth.session-token":{"name":"next-auth.session-token","value":"eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIn0..hush7RTHSXT_bw6_.onjonce2DiODfa32mghhdaZttzTKWC8EwODsWE7rl5jDjy8L8LyNAFdHlWoSxUQMEuu8_LcKZI1u9quaR1YRf8M_1JX51DG_Ta42F7QnS3BTXHGJE1ISQLDUCeDLoDz8B6EKxU0CvgPK_DizrryO5_bU9cTDUr6EbsUcIBbP_u-DDgzNjvO1Teqk2g23vF5pXmsN4EHMpz866OiP-hHg86XlHFnZM19Rdqqo0QkFSDpNo6iAyOsj3y1R6VD-4b7r5A5evEEkBcBZjXvDKyRSCtxA4XfY-MoJJakQy1XRrv_h-ueBxStMkO3EPIdOosbC60AG-WeIi5oBf_PBzOFILk8PDiOs1_KTkLKIYx59WUxUs7ph8ExUhcbMvqZR8cR4UiO0.fCFvcQxGWWqK5sc3XSFDQg"}}

我认为错误是我解释cookie的方式导致写入失败,但我不知道如何修复...

你能帮我吗?

cookies next.js middleware
1个回答
0
投票

你找到解决办法了吗?就我而言,我使用 next-intl 进行国际化,但如果用户已连接(使用 Supabase),我想在使用 next-intl 的中间件之前设置 NEXT_LOCALE cookie。如果它与导航器或位置中设置的语言相关联,则允许用户使用首选语言。

这就是我的真实情况

middleware
:

import { createMiddlewareClient } from '@supabase/auth-helpers-nextjs'
import { NextRequest, NextResponse } from 'next/server'
import createIntlMiddleware from 'next-intl/middleware'
import { User } from './types/type.user';

const locales = ['en', 'fr'];

const intlMiddleware = createIntlMiddleware({
  locales,
  defaultLocale: 'en',
  localePrefix: 'never',
})

export async function middleware(req: NextRequest) {
  const res = NextResponse.next()
  const supabase = createMiddlewareClient({ req, res })
  const { data: { session } } = await supabase.auth.getSession();
  const { data: user } = await supabase.from('user').select('*').eq('id', session?.user.id).single() as { data: User }
  if (user) {
    res.cookies.set(
      {
        name: 'NEXT_LOCALE',
        value: user.language,
        maxAge: 365 * 24 * 60 * 60,
        path: '/',
        sameSite: 'strict',
        priority: 'medium'
    });
  }
  return intlMiddleware(req);
}

export const config = {
  matcher: ['/((?!api|_next|_vercel|.*\\..*).*)']
}

在此示例中,cookie 永远不会改变。但是如果我在 intMiddleware(req) 之前返回 res 变量,则 cookie 被设置(但显然 intlMiddleware 永远不会被调用)

© www.soinside.com 2019 - 2024. All rights reserved.