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

NextJS与AWS Amplify的认证路由配置问题求助

NextJS + AWS Amplify 认证路由控制实现方案

核心实现思路

通过NextJS中间件拦截路由请求,结合AWS Amplify Auth API校验用户状态,根据状态重定向到对应页面。同时在页面组件内添加兜底校验,避免中间件失效的情况。

步骤1:确认Amplify配置正确

确保你的amplifyconfiguration.json已正确配置,且在NextJS项目中完成Amplify初始化:

// app/layout.tsx 或 pages/_app.tsx
import { Amplify } from 'aws-amplify';
import amplifyconfig from '@/amplifyconfiguration.json';

Amplify.configure(amplifyconfig);

步骤2:编写中间件(middleware.ts)

在项目根目录创建middleware.ts,实现路由拦截与状态校验:

import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
import { Auth } from 'aws-amplify';

export async function middleware(request: NextRequest) {
  const path = request.nextUrl.pathname;

  // 定义需要登录才能访问的路由
  const protectedRoutes = ['/dashboard', '/profile'];
  // 定义已登录用户禁止访问的路由
  const authRoutes = ['/login', '/register'];

  let isAuthenticated = false;
  try {
    // 跳过缓存实时校验用户登录状态
    await Auth.currentAuthenticatedUser({ bypassCache: true });
    isAuthenticated = true;
  } catch (err) {
    // 用户未登录时会抛出错误,直接捕获标记为未认证
    isAuthenticated = false;
  }

  // 已登录用户访问登录/注册页,重定向到仪表盘
  if (authRoutes.includes(path) && isAuthenticated) {
    return NextResponse.redirect(new URL('/dashboard', request.url));
  }

  // 未登录用户访问受保护路由,重定向到登录页
  if (protectedRoutes.includes(path) && !isAuthenticated) {
    return NextResponse.redirect(new URL('/login', request.url));
  }

  // 其他情况正常放行
  return NextResponse.next();
}

// 指定中间件生效的路由范围
export const config = {
  matcher: ['/dashboard/:path*', '/profile/:path*', '/login', '/register'],
};

步骤3:页面组件内添加兜底校验

为避免中间件因缓存或配置问题失效,在对应页面添加组件级校验:

受保护页面示例(app/dashboard/page.tsx)

'use client';
import { useEffect, useState } from 'react';
import { Auth } from 'aws-amplify';
import { useRouter } from 'next/navigation';

export default function Dashboard() {
  const router = useRouter();
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const checkAuth = async () => {
      try {
        await Auth.currentAuthenticatedUser();
      } catch (err) {
        router.push('/login');
      } finally {
        setLoading(false);
      }
    };
    checkAuth();
  }, [router]);

  if (loading) {
    return <div>加载中...</div>;
  }

  return <div>仪表盘内容</div>;
}

登录页面示例(app/login/page.tsx)

'use client';
import { useEffect, useState } from 'react';
import { Auth } from 'aws-amplify';
import { useRouter } from 'next/navigation';

export default function Login() {
  const router = useRouter();
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const checkAuth = async () => {
      try {
        await Auth.currentAuthenticatedUser();
        router.push('/dashboard');
      } catch (err) {
        // 用户未登录,正常显示登录页
      } finally {
        setLoading(false);
      }
    };
    checkAuth();
  }, [router]);

  if (loading) {
    return <div>加载中...</div>;
  }

  return <div>登录表单</div>;
}

常见问题排查

  • 调用Auth.currentAuthenticatedUser时必须添加bypassCache: true,避免缓存导致的状态判断延迟
  • 中间件的matcher配置要覆盖所有需要校验的路由,使用/:path*匹配子路由
  • 若使用App Router,Amplify初始化建议放在Client Component或layout.tsx的客户端逻辑中,避免 hydration 错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 12:23:33