Next.js 13中Next Auth与AWS Cognito凭证式授权集成求助
Next.js 13 + NextAuth.js + AWS Cognito 凭证式授权分步指南
1. 配置AWS Cognito用户池
- 登录AWS控制台进入Cognito服务,创建用户池
- 在「认证方式」中勾选「用户名」和「密码」,启用凭证登录模式
- 创建用户池客户端,记录以下关键信息:
- 用户池ID(User Pool ID)
- 客户端ID(Client ID)
- AWS区域(Region)
- 在Cognito控制台手动创建测试用户,用于后续验证
2. 安装依赖
执行命令安装所需包:
npm install next-auth @aws-sdk/client-cognito-identity-provider
3. 创建NextAuth配置文件(App Router)
在项目根目录下创建app/api/auth/[...nextauth]/route.ts,内容如下:
import NextAuth from "next-auth"; import Credentials from "next-auth/providers/credentials"; import { CognitoIdentityProviderClient, InitiateAuthCommand, } from "@aws-sdk/client-cognito-identity-provider"; const cognitoClient = new CognitoIdentityProviderClient({ region: process.env.AWS_REGION, }); export const authOptions = { providers: [ Credentials({ name: "Credentials", credentials: { username: { label: "Username", type: "text" }, password: { label: "Password", type: "password" }, }, async authorize(credentials) { if (!credentials?.username || !credentials?.password) return null; try { const command = new InitiateAuthCommand({ AuthFlow: "USER_PASSWORD_AUTH", ClientId: process.env.COGNITO_CLIENT_ID, AuthParameters: { USERNAME: credentials.username, PASSWORD: credentials.password, }, }); const response = await cognitoClient.send(command); if (response.AuthenticationResult) { const { AccessToken, IdToken, RefreshToken } = response.AuthenticationResult; return { id: credentials.username, name: credentials.username, accessToken: AccessToken, idToken: IdToken, refreshToken: RefreshToken, }; } return null; } catch (error) { console.error("Cognito认证失败:", error); return null; } }, }), ], session: { strategy: "jwt" }, callbacks: { async jwt({ token, user }) { if (user) { token.accessToken = user.accessToken; token.idToken = user.idToken; token.refreshToken = user.refreshToken; token.name = user.name; } return token; }, async session({ session, token }) { session.user.name = token.name; session.accessToken = token.accessToken; session.idToken = token.idToken; return session; }, }, pages: { signIn: "/login" }, }; const handler = NextAuth(authOptions); export { handler as GET, handler as POST };
4. 设置环境变量
在项目根目录的.env.local文件中添加:
AWS_REGION=你的AWS区域(如us-east-1) COGNITO_CLIENT_ID=你的Cognito客户端ID COGNITO_USER_POOL_ID=你的Cognito用户池ID NEXTAUTH_SECRET=随机生成密钥(可通过`openssl rand -hex 32`生成) NEXTAUTH_URL=http://localhost:3000(生产环境替换为实际域名)
5. 创建自定义登录页面
在app/login/page.tsx中编写登录表单:
"use client"; import { signIn } from "next-auth/react"; import { useState } from "react"; export default function LoginPage() { const [username, setUsername] = useState(""); const [password, setPassword] = useState(""); const [error, setError] = useState(""); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); setError(""); const result = await signIn("credentials", { username, password, redirect: false, }); if (result?.error) setError("用户名或密码错误"); else window.location.href = "/"; }; return ( <div className="max-w-md mx-auto mt-10 p-6 border rounded-lg"> <h2 className="text-xl font-bold mb-4">登录</h2> {error && <p className="text-red-500 mb-4">{error}</p>} <form onSubmit={handleSubmit}> <div className="mb-4"> <label className="block mb-1">用户名</label> <input type="text" value={username} onChange={(e) => setUsername(e.target.value)} className="w-full p-2 border rounded" required /> </div> <div className="mb-4"> <label className="block mb-1">密码</label> <input type="password" value={password} onChange={(e) => setPassword(e.target.value)} className="w-full p-2 border rounded" required /> </div> <button type="submit" className="w-full bg-blue-500 text-white p-2 rounded hover:bg-blue-600" > 登录 </button> </form> </div> ); }
6. 保护路由示例
创建受保护页面app/dashboard/page.tsx:
import { getServerSession } from "next-auth/next"; import { authOptions } from "../api/auth/[...nextauth]/route"; import { redirect } from "next/navigation"; export default async function DashboardPage() { const session = await getServerSession(authOptions); if (!session) redirect("/login"); return ( <div className="max-w-md mx-auto mt-10"> <h2 className="text-xl font-bold mb-4">仪表盘</h2> <p>欢迎,{session.user.name}!</p> <p>访问令牌:{session.accessToken}</p> </div> ); }
7. 测试流程
- 启动开发服务器:
npm run dev - 访问
http://localhost:3000/login,输入Cognito测试用户凭证 - 登录成功后自动跳转到仪表盘页面,未登录时访问仪表盘会重定向到登录页
内容的提问来源于stack exchange,提问作者Vishal
相关产品推荐
相关产品推荐

