Next.js中next-auth Session属性远程环境无法渲染的问题求助
问题描述
我开发了一个使用next-auth库做身份认证的Next.js应用,用Cognito作为身份提供商,需要在导航栏渲染用户邮箱。我通过useSession钩子从Session中获取用户邮箱并渲染,代码如下:
import {useSession} from 'next-auth/react' ... const { data: session } = useSession() ... return ( <Dropdown.Item panel style={{ padding: 10, width: 160 }}> <p>Signed in as</p> <strong>{session?.user?.email}</strong> </Dropdown.Item> ... )
这个逻辑在本地环境正常运行,但部署到远程环境后无法渲染用户邮箱。请问这是默认行为吗?有什么更好的解决方案?
我的api/auth/[...nextauth].tsx文件代码如下:
export const authOptions: NextAuthOptions = { providers: [ CognitoProvider({ clientId: process.env.COGNITO_CLIENT_ID || '', clientSecret: process.env.COGNITO_CLIENT_SECRET || '', issuer: process.env.COGNITO_ISSUER || '', }) ], secret:'sdg=', callbacks: { async jwt({token, account}) { if (account) { token.access_token = account.access_token token.id_token = account.id_token } return token }, async session({ session, token }) { session.access_token = token.access_token; session.id_token = token.id_token; return session; }, } } export default NextAuth(authOptions)
原因分析
这不是next-auth的默认行为,问题出在你的回调逻辑里:
jwt回调没有把用户邮箱等信息存入token中,导致后续session重建时没有数据源session回调仅挂载了access_token和id_token,没有将用户邮箱同步到session.user对象
本地环境能正常显示,大概率是因为初始登录时的session缓存包含用户信息,但远程环境中session是从JWT重新构建的,因此缺失了邮箱数据。
解决方案
修改jwt和session回调,把用户邮箱同步到token和session中,同时优化secret的配置方式:
export const authOptions: NextAuthOptions = { providers: [ CognitoProvider({ clientId: process.env.COGNITO_CLIENT_ID || '', clientSecret: process.env.COGNITO_CLIENT_SECRET || '', issuer: process.env.COGNITO_ISSUER || '', // 可选:明确指定需要获取的用户信息范围 scope: "openid email profile" }) ], // 不要硬编码secret,用环境变量配置,远程环境必须设置该变量 secret: process.env.NEXTAUTH_SECRET || 'sdg=', callbacks: { async jwt({ token, account, user }) { // 首次登录时,将用户信息存入token if (user) { token.email = user.email; // 如需其他用户信息(如昵称),可在此添加 } // 保留token和id_token if (account) { token.access_token = account.access_token; token.id_token = account.id_token; } return token; }, async session({ session, token }) { // 将token中的邮箱同步到session.user session.user.email = token.email as string; // 保留原有token信息 session.access_token = token.access_token; session.id_token = token.id_token; return session; }, } } export default NextAuth(authOptions)
额外注意:
- 确保Cognito应用客户端已开启获取用户邮箱的权限,认证流程中包含
email范围请求 - 远程环境必须配置
NEXTAUTH_SECRET环境变量,否则session加密会出现异常,也可能导致用户信息无法正常传递
内容的提问来源于stack exchange,提问作者ahkam
相关产品推荐
相关产品推荐

