Next.js项目中可使用自定义登录表单替换AWS Cognito托管UI吗?
完全可以用自研自定义表单替换AWS Cognito提供的托管UI
你原来的配置使用的是Cognito OAuth Provider,会默认跳转到Cognito托管UI完成认证,要切换为自定义表单,只需要改用Credentials Provider配合Cognito官方SDK做本地身份校验即可,具体实现步骤如下:
前置准备
- 安装Cognito官方SDK用于身份校验:
npm install amazon-cognito-identity-js - 前往AWS Cognito控制台,在你使用的用户池客户端配置中,开启ALLOW_USER_PASSWORD_AUTH认证流
调整NextAuth配置
替换你原有配置中的Cognito Provider为Credentials Provider,示例配置如下:
import NextAuth from "next-auth"; import CredentialsProvider from "next-auth/providers/credentials"; import { CognitoUserPool, CognitoUser, AuthenticationDetails } from "amazon-cognito-identity-js"; const userPool = new CognitoUserPool({ UserPoolId: process.env.COGNITO_USER_POOL_ID, ClientId: process.env.COGNITO_CLIENT, }); export default NextAuth({ session: { strategy: "jwt" }, providers: [ CredentialsProvider({ name: "credentials", credentials: { username: { label: "用户名", type: "text" }, password: { label: "密码", type: "password" }, }, async authorize(credentials) { if (!credentials?.username || !credentials?.password) { return null; } const authenticationDetails = new AuthenticationDetails({ Username: credentials.username, Password: credentials.password, }); const cognitoUser = new CognitoUser({ Username: credentials.username, Pool: userPool, }); return new Promise((resolve) => { cognitoUser.authenticateUser(authenticationDetails, { onSuccess: (session) => { resolve({ id: cognitoUser.getUsername(), name: cognitoUser.getUsername(), email: credentials.username, accessToken: session.getAccessToken().getJwtToken(), idToken: session.getIdToken().getJwtToken(), refreshToken: session.getRefreshToken().getToken(), }); }, onFailure: () => { resolve(null); }, }); }); }, }), ], callbacks: { async jwt({ token, user }) { if (user) { token.accessToken = user.accessToken; token.idToken = user.idToken; token.refreshToken = user.refreshToken; } return token; }, async session({ session, token }) { session.accessToken = token.accessToken; session.idToken = token.idToken; session.refreshToken = token.refreshToken; return session; }, }, });
开发自定义登录表单
在你需要的页面开发自定义表单,收集账号密码后调用NextAuth提供的signIn方法触发认证即可,示例代码:
import { useState } from "react"; import { signIn } from "next-auth/react"; export default function LoginPage() { const [username, setUsername] = useState(""); const [password, setPassword] = useState(""); const handleSubmit = async (e) => { e.preventDefault(); await signIn("credentials", { username, password, callbackUrl: "/dashboard", }); }; return ( <form onSubmit={handleSubmit}> <input type="text" value={username} onChange={(e) => setUsername(e.target.value)} placeholder="用户名/邮箱" required /> <input type="password" value={password} onChange={(e) => setPassword(e.target.value)} placeholder="密码" required /> <button type="submit">登录</button> </form> ); }
其他注意事项
- 注册、找回密码、MFA校验这类功能都可以通过
amazon-cognito-identity-js的对应API实现,无需依赖Cognito托管UI - 你需要自行处理认证过程中的错误提示,比如密码错误、账号未验证、用户不存在等场景
- 原有Cognito OAuth相关的能力不受影响,如果需要保留第三方登录能力,可以同时在NextAuth配置中保留Cognito Provider
内容的提问来源于stack exchange,提问作者Nahashon Muriithi
相关产品推荐
相关产品推荐

