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

Next.js13使用next-auth搭建自定义登录门户的路由导入问题求助

Next.js 13 + NextAuth.js 自定义登录门户解决方案

一、解决useRouter导入错误

Next.js 13的App Router(app目录)彻底弃用了next/router,统一改用next/navigation提供的导航API,直接替换导入语句即可:

// 旧写法(仅适用于Pages Router)
import { useRouter } from 'next/router'

// 新写法(App Router必须用这个)
import { useRouter } from 'next/navigation'

如果你的项目还在使用Pages Router(pages目录),可以继续用next/router,但App Router下必须切换到新的导入路径。

二、简化自定义登录/登出实现

1. 先配置NextAuth核心路由

在app/api/auth/[...nextauth]/route.js中完成基础配置,这里以常用的账号密码登录(Credentials提供者)为例:

import NextAuth from 'next-auth'
import CredentialsProvider from 'next-auth/providers/credentials'

export const authOptions = {
  providers: [
    CredentialsProvider({
      name: '账号密码登录',
      credentials: {
        email: { label: '邮箱', type: 'email' },
        password: { label: '密码', type: 'password' }
      },
      // 这里替换成你的用户校验逻辑(比如查数据库、调用后端接口)
      async authorize(credentials) {
        if (!credentials?.email || !credentials?.password) return null
        
        // 示例:模拟校验通过,返回用户信息
        const user = { id: '1', name: '测试用户', email: credentials.email }
        return user
      }
    })
  ],
  session: { strategy: 'jwt' },
  // 指定自定义登录页的路径
  pages: { signIn: '/login' }
}

const handler = NextAuth(authOptions)
export { handler as GET, handler as POST }

2. 自定义登录页面(app/login/page.js)

用NextAuth提供的signIn方法快速实现登录逻辑,结合新的useRouter控制跳转:

'use client'
import { useState } from 'react'
import { signIn } from 'next-auth/react'
import { useRouter } from 'next/navigation'

export default function LoginPage() {
  const [email, setEmail] = useState('')
  const [password, setPassword] = useState('')
  const router = useRouter()

  const handleLogin = async (e) => {
    e.preventDefault()
    // 调用登录方法,禁用自动跳转以便手动控制
    const result = await signIn('credentials', {
      email,
      password,
      redirect: false
    })

    if (result.ok) {
      router.push('/dashboard') // 登录成功跳转到目标页面
    } else {
      alert(result.error) // 显示登录失败提示
    }
  }

  return (
    <form onSubmit={handleLogin} style={{ maxWidth: '300px', margin: '2rem auto' }}>
      <input
        type="email"
        value={email}
        onChange={(e) => setEmail(e.target.value)}
        placeholder="请输入邮箱"
        required
        style={{ display: 'block', width: '100%', margin: '0.5rem 0', padding: '0.5rem' }}
      />
      <input
        type="password"
        value={password}
        onChange={(e) => setPassword(e.target.value)}
        placeholder="请输入密码"
        required
        style={{ display: 'block', width: '100%', margin: '0.5rem 0', padding: '0.5rem' }}
      />
      <button type="submit" style={{ width: '100%', padding: '0.5rem', cursor: 'pointer' }}>
        登录
      </button>
    </form>
  )
}

3. 自定义登出按钮

用signOut方法实现登出,同样结合useRouter控制跳转:

'use client'
import { signOut } from 'next-auth/react'
import { useRouter } from 'next/navigation'

export default function LogoutButton() {
  const router = useRouter()

  const handleLogout = async () => {
    await signOut({ redirect: false })
    router.push('/login') // 登出后跳转到登录页
  }

  return <button onClick={handleLogout} style={{ cursor: 'pointer' }}>登出</button>
}

4. 保护路由示例

用useSession判断用户登录状态,未登录则强制跳转:

'use client'
import { useSession } from 'next-auth/react'
import { useEffect } from 'react'
import { useRouter } from 'next/navigation'

export default function ProtectedPage() {
  const { data: session, status } = useSession()
  const router = useRouter()

  useEffect(() => {
    if (status === 'unauthenticated') {
      router.push('/login')
    }
  }, [status, router])

  if (status === 'loading') {
    return <div>加载中...</div>
  }

  return <div>欢迎,{session.user.name}!这是仅登录用户可访问的页面</div>
}

内容的提问来源于stack exchange,提问作者Bibesh Gurung

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 01:00:09