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

在Next.js中使用Auth.js同时实现OAuth认证与API接口Basic认证的配置问题求助

在Next.js中使用Auth.js同时实现OAuth认证与API接口Basic认证的配置问题求助

我现在遇到了一个头疼的配置问题:我想在Next.js项目里同时实现OAuth(Google登录)用户认证和API接口的Basic认证保护,但目前的配置完全跑不通——除非我删掉Basic认证的代码,还把API路由从认证规则里排除,这种情况下单独用OAuth认证是完全正常的。

我把相关配置代码和遇到的错误都贴出来,希望能得到大家的帮助:

相关配置文件

auth.config.ts

import type { NextAuthConfig, Session } from 'next-auth';
import Google from "next-auth/providers/google"
import { SupabaseAdapter } from "@auth/supabase-adapter"
import { NextRequest } from 'next/server';

export const authConfig = {
  pages: {
    signIn: '/login'
  },
  callbacks: {
    authorized({ auth, request: { nextUrl }} : {auth: null | Session, request: NextRequest}) {
      const isLoggedIn = !!auth?.user;
      const isOnHomePage = nextUrl.pathname === '/';

      if (isOnHomePage) {
        if (isLoggedIn) {
          return true;
        }
        return false; // 未认证用户重定向到登录页
      } else if (isLoggedIn) {
        return Response.redirect(new URL('/', nextUrl))
      }
      return true;
    }
  },
  providers: [Google],
  adapter: SupabaseAdapter({
    url: process.env.SUPABASE_URL!,
    secret: process.env.SUPABASE_SERVICE_ROLE_KEY!,
  })
} satisfies NextAuthConfig;

auth.ts

import NextAuth from "next-auth";
import { authConfig } from './auth.config';

export const { handlers, signIn, signOut, auth } = NextAuth(authConfig)

middleware.ts

import NextAuth from 'next-auth';
import { authConfig } from './auth.config';
import { NextResponse } from 'next/server';

const { auth } = NextAuth(authConfig);

export default auth((req) => {
  const url = new URL(req.url);

  // 明确跳过NextAuth的API路由和session端点
  if (url.pathname.startsWith('/api/auth/') || url.pathname === '/api/session') {
    return NextResponse.next();
  }

  if (url.pathname.startsWith('/api/')) {
    const authHeader = req.headers.get('authorization') ?? '';

    if (!authHeader.startsWith('Basic ')) {
      return new NextResponse('Unauthorized', {
        status: 401,
        headers: {
          'WWW-Authenticate': 'Basic realm="Restricted"'
        },
      });
    }

    const base64 = authHeader.slice(6);
    let decoded = '';
    try {
      if (typeof Buffer !== 'undefined' && typeof Buffer.from === 'function') {
        decoded = Buffer.from(base64, 'base64').toString('utf-8');
      } else if (typeof atob === 'function') {
        decoded = atob(base64);
      } else {
        return new NextResponse('Unauthorized', {
          status: 401,
          headers: {
            'WWW-Authenticate': 'Basic realm="Restricted"'
          },
        });
      }
    } catch (err) {
      return new NextResponse('Unauthorized', {
        status: 401,
        headers: {
          'WWW-Authenticate': 'Basic realm="Restricted"'
        },
      });
    }

    const [username, password] = decoded.split(':');
    const validUsername = process.env.API_BASIC_AUTH_USER;
    const validPassword = process.env.API_BASIC_AUTH_PASS;

    if (!validUsername || !validPassword || username !== validUsername || password !== validPassword) {
      return new NextResponse('Unauthorized', {
        status: 401,
        headers: {
          'WWW-Authenticate': 'Basic realm="Restricted"'
        },
      });
    }

    // Basic认证通过,放行到API处理器
    return NextResponse.next();
  }

  // 非API路由:继续执行(NextAuth会处理重定向/认证页逻辑)
  return NextResponse.next();
});

export const config = {
  // 对API路由和应用页面应用中间件;不要使用否定匹配项
  matcher: [
    '/api/:path*',
    '/((?!_next/static|_next/image|.*\\.png$).*)'
  ],
};

遇到的错误

在浏览器控制台里弹出了这个错误:

providers.tsx:36 ClientFetchError: Unexpected token '<', "<!DOCTYPE "... is not valid JSON.
    at fetchData (client.js:39:22)
    at async getSession (react.js:97:21)
    at async SessionProvider.useEffect [as _getSession] (react.js:253:43)

看起来是Auth.js在获取session的时候拿到了HTML内容而不是预期的JSON,导致解析失败。我猜可能是middleware的逻辑和NextAuth的session处理有冲突,但实在不知道该怎么调整,求大佬们指点!

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 06:44:29