NextAuth.js报错:不支持HTTP GET请求,signIn函数无法正常工作
解决NextAuth.js报错:"Error: This action with HTTP GET is not supported by NextAuth.js"
问题场景
使用Auth.js的signIn函数搭建静态登录页面时触发上述错误,尝试通过handleSubmit调用signIn授权用户会话却收到HTTP错误。
相关代码
Pages > API > Auth > [nextauth].js
import NextAuth from "next-auth" import CredentialsProvider from "next-auth/providers/credentials" export default NextAuth ({ providers: [ CredentialsProvider({ name: "Credentials", credentials: { username: { label: "Username", type:"text", placeholder: 'user'}, password: { label: "Password", type:"text", placeholder:'password'}, }, async authorize(credentials) { if (credentials == null) return null; { //login const { username, password } = credentials; if (!user) { console.log('user is not found!') } const isMatch = await user.matchPassword(password); if(!isMatch) { throw new Error("Username or Password is incorrect") } return user; } } }) ], callbacks: { async signIn({ user, account, profile, email, credentials }) { const isAllowedToSignIn = true if (isAllowedToSignIn) { return true } else { return false } } }, async redirect({url, baseUrl}) { // Allows relative callback URLs if(url.startsWith("/")) return `${baseUrl}${url}` // Allows callback URLs on the same origin else if ( new URL(url).origin === baseUrl) return url return baseUrl }, async session({session, user, token}) { return session }, async jwt({token, user, account, profile, isNewUser}) { return token }, pages: { signIn: '/login.jsx', }, secret: process.env.NEXTAUTH_SECRET, callbacks: { async jwt({token, user }) { if (user) { token.id = user._id.toString(); // Convert ObjectID to string } } } })
Login.jsx文件
import React, { useState } from "react" import Link from 'next/link'; import styled from 'styled-components'; import { Spacer } from "@nextui-org/react"; import { useRouter } from "next/router"; import {signIn} from "next-auth/react" const Login = () => { const [user, setUser] = useState(''); const [pass, setPass] = useState(''); const router = useRouter(); const handleSubmit = (e) =>{ e.preventDefault(e); console.log(user); console.log(pass); signIn(); if (!user) { window.alert('Please provide username') } else if (!pass) { window.alert('Please provide password') } else { window.alert('Welcome' + ' ' + {user}) router.push('../user-pages/profile') } } return ( <div className="authform"> <div className="form"> <form> <Spacer y={1} /> <input name="userName"/> <label style={{color: "white", translate: -5}} form="userName"> Username <input value={user} onChange={(e) => setUser(e.target.value)} type='username' placeholder='Username' id="Username" name='Username'/> </label> <Spacer y= {.25} /> <br /> <label style={{color: "White", translate: -5}} form="Password">Password</label> <input value={pass} onChange={(e) => setPass(e.target.value)}type="Password" placeholder="******" id='Password' name='Password' /> <button type='submit' onClick={signIn}>Log In</button> </form> <Spacer y={.75} /> <a style={{color: "white"}} href='#'>Forgot Password?</a> <Spacer y={.25} /> <Link style={{color: "white"}} href='../user-pages/signup'> Dont have an account? Register here! </Link> </div> </div> ); }; export default Login;
错误原因及修复方案
1. Login.jsx核心问题(直接触发GET请求错误)
- 按钮同时绑定
type='submit'和onClick={signIn},点击时会发起两次请求,其中onClick直接调用signIn()会触发不被允许的GET请求。 - 表单未绑定
onSubmit到handleSubmit,自定义校验逻辑无法正确触发。 signIn调用未传递provider和表单数据,NextAuth无法识别认证请求。- 存在冗余表单字段干扰数据收集。
修正后的Login.jsx:
import React, { useState } from "react" import Link from 'next/link'; import styled from 'styled-components'; import { Spacer } from "@nextui-org/react"; import { useRouter } from "next/router"; import { signIn } from "next-auth/react" const Login = () => { const [username, setUsername] = useState(''); const [password, setPassword] = useState(''); const router = useRouter(); const handleSubmit = async (e) => { e.preventDefault(); // 前端基础校验 if (!username) { window.alert('请输入用户名'); return; } if (!password) { window.alert('请输入密码'); return; } // 指定credentials provider并传递表单数据 const result = await signIn('credentials', { username, password, redirect: false // 手动处理跳转 }); if (result.ok) { window.alert(`欢迎回来,${username}`); router.push('/user-pages/profile'); } else { window.alert(result.error || '登录失败,请检查用户名或密码'); } }; return ( <div className="authform"> <div className="form"> <form onSubmit={handleSubmit}> <Spacer y={1} /> <label style={{ color: "white", translate: -5 }} htmlFor="Username"> Username <input value={username} onChange={(e) => setUsername(e.target.value)} type='text' placeholder='Username' id="Username" name='username' // 字段名与NextAuth配置一致 /> </label> <Spacer y={.25} /> <br /> <label style={{ color: "White", translate: -5 }} htmlFor="Password">Password</label> <input value={password} onChange={(e) => setPassword(e.target.value)} type="password" placeholder="******" id='Password' name='password' // 字段名与NextAuth配置一致 /> <button type='submit'>Log In</button> </form> <Spacer y={.75} /> <a style={{ color: "white" }} href='#'>Forgot Password?</a> <Spacer y={.25} /> <Link style={{ color: "white" }} href='/user-pages/signup'>Dont have an account? Register here!</Link> </div> </div> ); }; export default Login;
2. [nextauth].js核心问题
- 重复定义
callbacks,后面的配置会覆盖前面的signIn回调。 authorize函数中user变量未定义,缺少实际用户查询逻辑。pages.signIn路径错误,不需要加.jsx后缀。redirect、session等顶级属性位置错误,被错误嵌套。
修正后的[nextauth].js:
import NextAuth from "next-auth" import CredentialsProvider from "next-auth/providers/credentials" // 引入你的用户模型或查询方法,替换下面的占位逻辑 // import User from '../../../models/User'; export default NextAuth({ providers: [ CredentialsProvider({ name: "Credentials", credentials: { username: { label: "Username", type: "text", placeholder: 'user' }, password: { label: "Password", type: "password", placeholder: 'password' }, }, async authorize(credentials) { if (!credentials) return null; const { username, password } = credentials; // 替换为实际的用户查询逻辑,比如从数据库查找 // const user = await User.findOne({ username }); const user = null; // 临时占位,需替换 if (!user) { throw new Error("用户名不存在"); } // 替换为实际的密码校验逻辑,比如bcrypt.compare // const isMatch = await bcrypt.compare(password, user.password); const isMatch = false; // 临时占位,需替换 if (!isMatch) { throw new Error("用户名或密码错误"); } return user; } }) ], callbacks: { async signIn({ user, account, profile, email, credentials }) { return true; // 可根据需求添加额外登录校验 }, async jwt({ token, user }) { if (user) { token.id = user._id?.toString(); } return token; // 必须返回token,否则数据丢失 }, async session({ session, token }) { if (token.id) { session.user.id = token.id; } return session; } }, redirect({ url, baseUrl }) { if (url.startsWith("/")) return `${baseUrl}${url}`; if (new URL(url).origin === baseUrl) return url; return baseUrl; }, pages: { signIn: '/login', // 修正页面路径 }, secret: process.env.NEXTAUTH_SECRET, })
关键注意事项
- Credentials认证仅支持POST请求,禁止通过GET调用
signIn。 signIn调用必须指定'credentials'作为provider,且表单字段名要与NextAuth配置中的credentials完全匹配。authorize函数需返回用户对象(或null),校验失败时抛出的错误会被signIn返回结果捕获。
内容的提问来源于stack exchange,提问作者Freeman
相关产品推荐
相关产品推荐

