Next.js 13 App目录下AWS Amplify SSR认证配置失败求助
Next.js App目录中AWS Amplify服务端配置失败问题解答
问题描述
用户在Next.js App目录中配置AWS Amplify以实现服务端运行,配置代码如下:
import { Amplify } from "aws-amplify"; interface Props { children: React.ReactNode; } const awsconfig = { region: process.env.NEXT_PUBLIC_COGNITO_REGION, userPoolId: process.env.NEXT_PUBLIC_COGNITO_USER_POOL_ID, userPoolWebClientId: process.env.NEXT_PUBLIC_COGNITO_USER_POOL_WEB_CLIENT_ID, }; Amplify.configure({ Auth: awsconfig, ssr: true }); export const AwsAmplifyProvider = ({ children }: Props) => { return <> {children} </>; };
服务端运行时始终出现以下错误:
51:29.191 AuthError - Error: Amplify has not been configured correctly.
注:仅服务端运行时出现该问题,客户端使用"use client"标识时配置完全正常。
问题原因
- 服务端配置时机错误:在Next.js App Router中,服务端组件的顶层作用域代码会在服务器启动时执行一次,而非每次请求时执行。这种全局配置方式会导致并发请求下Amplify配置被共享或未正确初始化,引发配置异常。
- 环境变量加载验证缺失:虽然
NEXT_PUBLIC_前缀的环境变量支持服务端和客户端共享,但存在服务端渲染时变量未正确注入的可能,导致配置参数为空。
解决方案
方案一:服务端组件内按需配置Amplify
在服务端组件的函数内部而非顶层作用域执行Amplify配置,确保每次请求都能正确初始化:
import { Amplify, withSSRContext } from "aws-amplify"; export async function ServerAuthComponent() { // 每次请求时重新配置Amplify const awsconfig = { region: process.env.NEXT_PUBLIC_COGNITO_REGION, userPoolId: process.env.NEXT_PUBLIC_COGNITO_USER_POOL_ID, userPoolWebClientId: process.env.NEXT_PUBLIC_COGNITO_USER_POOL_WEB_CLIENT_ID, }; Amplify.configure({ Auth: awsconfig, ssr: true }); // 使用SSR上下文处理认证逻辑 const SSR = withSSRContext(); try { const user = await SSR.Auth.currentAuthenticatedUser(); return <div>当前登录用户:{user.username}</div>; } catch (err) { return <div>未登录</div>; } }
方案二:客户端Provider配合服务端SSR上下文
通过客户端组件初始化Amplify配置,服务端组件使用withSSRContext对接认证状态:
- 创建客户端Provider组件
AmplifyProvider.tsx:
"use client"; import { Amplify } from "aws-amplify"; import { PropsWithChildren } from "react"; // 客户端初始化Amplify配置 Amplify.configure({ Auth: { region: process.env.NEXT_PUBLIC_COGNITO_REGION, userPoolId: process.env.NEXT_PUBLIC_COGNITO_USER_POOL_ID, userPoolWebClientId: process.env.NEXT_PUBLIC_COGNITO_USER_POOL_WEB_CLIENT_ID, }, ssr: true, }); export default function AmplifyProvider({ children }: PropsWithChildren) { return <>{children}</>; }
- 在根布局
layout.tsx中引入Provider:
import AmplifyProvider from "./AmplifyProvider"; export default function RootLayout({ children, }: { children: React.ReactNode; }) { return ( <html lang="zh-CN"> <body> <AmplifyProvider>{children}</AmplifyProvider> </body> </html> ); }
- 服务端组件中使用SSR上下文:
import { withSSRContext } from "aws-amplify"; export default async function ServerPage() { const SSR = withSSRContext(); try { const user = await SSR.Auth.currentAuthenticatedUser(); return <div>欢迎回来,{user.username}</div>; } catch (err) { return <div>请先登录</div>; } }
额外验证步骤
- 在服务端组件中打印
process.env.NEXT_PUBLIC_COGNITO_REGION等值,确认环境变量是否在服务端正常加载。 - 确保
.env.local文件中的变量拼写正确,且构建/运行时已注入环境变量。
内容的提问来源于stack exchange,提问作者Gourav Kumar
相关产品推荐
相关产品推荐

