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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 22:38:23