繁体   English   中英

下一个身份验证 email 提供程序未触发

[英]Next auth email provider is not triggering

在我决定创建自定义登录页面之前,Next-Auth 一直对我很好。

我的谷歌登录工作完美,我可以看到调试器中围绕令牌生成和使用我的适配器创建 session 进行了很多工作。

但是,当我尝试使用 email 验证登录时,它只会从输入框中清除 email,然后什么也不做。 该表单直接来自下一个身份验证文档。

我已经三次检查了我的 sendgrid apikey 的设置,它们都在 my.env.local 文件中正确设置。

"/pages/api/auth/[...nextauth].js"

import NextAuth from "next-auth"
import GoogleProvider from "next-auth/providers/google"
import EmailProvider from "next-auth/providers/email"
import { FirestoreAdapter } from "@next-auth/firebase-adapter"

const authOptions = {
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_ID,
      clientSecret: process.env.GOOGLE_SECRET,
    }),
    EmailProvider({
      server: {
        host: process.env.EMAIL_SERVER_HOST,
        port: process.env.EMAIL_SERVER_PORT,
        auth: {
          user: process.env.EMAIL_SERVER_USER,
          pass: process.env.EMAIL_SERVER_PASSWORD,
        }
      },
      from: process.env.EMAIL_FROM
    }),
  ],
  session: {
    jwt: true,
  },
  adapter: FirestoreAdapter({
    apiKey: process.env.FIREBASE_API_KEY,
    appId: process.env.FIREBASE_APP_ID,
    authDomain: process.env.FIREBASE_AUTH_DOMAIN,
    databaseURL: process.env.FIREBASE_DATABASE_URL,
    projectId: process.env.FIREBASE_PROJECT_ID,
    storageBucket: process.env.FIREBASE_STORAGE_BUCKET,
    messagingSenderId: process.env.FIREBASE_MESSAGING_SENDER_ID
  }),
  theme: ({
    colorScheme: "dark",
  }),
  pages: {
    signIn: "/auth/signin",
    newUser: "/auth/signup",
  },
  debug: true,
  callbacks: {
    async signIn({ user, account, profile, email, credentials }) {
      return true
    },
    async redirect({ url, baseUrl }) {
      return baseUrl
    },
    async session({ session, user, token }) {
      return session
    },
    async jwt({ token, user, account, profile, isNewUser }) {
      return token
    }
  }
}
export default NextAuth(authOptions)

这是我的自定义页面...

"/pages/auth/signin.js"

import React from 'react'
import {getProviders, signIn, getCsrfToken} from 'next-auth/react'
import styles from '../../styles/signin.module.css'
import Logo from '../../components/Logo'

export default function SignIn ({ csrfToken, providers }) {

  return (
    <div>
      <div className={styles.content}>
        <div className={styles.cardWrapper}>
          <Logo className={styles.logo}/>
          <div className={styles.cardContent}>
            <div className={styles.emailForm}>
              <form method="post" action="/api/auth/signin/email">
                <input name="csrfToken" type="hidden" defaultValue={csrfToken} />
                <input type="text" id="email" name="email" placeholder="Email" />
                <button type="submit">Sign in with Email</button>
              </form>
            </div>
            <hr />
            {Object.values(providers).map((provider) => {
              if (provider.name === "Email") {
                return
              }
              return (
                <div key={provider.name}>
                  <button onClick={() => signIn(provider.id)}>
                    Sign in with {provider.name}
                  </button>
                </div>
              )
            })}
          </div>
        </div>
      </div>
    </div>
  )
}

export async function getServerSideProps(context) {
  const csrfToken = await getCsrfToken(context)
  const providers = await getProviders(context)
  return {
    props: { csrfToken },
    props: { providers },
  }
}

编辑:安装的依赖项

"next": "^12.2.5",
"next-auth": "^4.10.3",
"nodemailer": "^6.7.8",
"react": "18.2.0",
"react-dom": "18.2.0",
"swiper": "^8.3.2",
"swr": "^1.3.0"
"@next-auth/firebase-adapter": "^1.0.1",
"@types/node": "^18.7.13",
"core-js": "^3.25.0",
"firebase": "^9.9.3",
"fs": "^0.0.1-security",

编辑:环境设置

NEXTAUTH_URL=http://localhost:3000
NEXTAUTH_SECRET=REDACTED SECRET

EMAIL_SERVER_HOST=smtp.sendgrid.net
EMAIL_SERVER_PORT=587
EMAIL_SERVER_USER=apikey
EMAIL_SERVER_PASSWORD=REDACTED (SET AS THE API KEY PROVIDED BY SENDGRID)
EMAIL_FROM=REDACTED (SET AS VERIFIED SINGLE USER EMAIL ADDRESS IN SENDGRID)

还设置了以下...

FIREBASE_API_KEY=REDACTED
FIREBASE_AUTH_DOMAIN=REDACTED
FIREBASE_PROJECT_ID=REDACTED
FIREBASE_STORAGE_BUCKET=REDACTED
FIREBASE_MESSAGING_SENDER_ID=REDACTED
FIREBASE_APP_ID=REDACTED
FIREBASE_DATABASE_URL=REDACTED

编辑:“/pages/_app.js” - 添加主应用程序以防问题是由我包装组件的方式引起的。

import React from 'react'
import App from 'next/app'
import { SessionProvider } from "next-auth/react"
import Layout from "../components/Layout.js"
import AccountSettingsLayout from '../components/AccountSettingsLayout'
import { SWRConfig } from 'swr'


import '../styles/globals.css'

class MyApp extends App {
  render() {
    const { Component, router, pageProps: { session, ...pageProps }} = 
this.props

  if (router.pathname.startsWith('/auth/')) {
    return (
      <React.StrictMode>
        <SessionProvider session={session}>
          <SWRConfig>
            <AccountSettingsLayout>
              <Component {...pageProps} />
            </AccountSettingsLayout>
          </SWRConfig> 
        </SessionProvider>
      </React.StrictMode>
    )
  }

  return (
    <React.StrictMode>
      <SessionProvider session={session}>
        <SWRConfig>
          <Layout>
            <Component {...pageProps} />
          </Layout>
        </SWRConfig> 
      </SessionProvider>
    </React.StrictMode>
  )
}}

export default MyApp

更新:当输入 email 地址并单击提交时,我在 URL 中得到以下更改。

开始 URL = http://localhost:3000/auth/signin

提交后= http://localhost:3000/auth/signin?callbackUrl=http%3A%2F%2Flocalhost%3A3000

更新 30.08.2022 - 我可以在终端中看到以下内容......等待 - 编译 /_error(客户端和服务器)......但是事件在没有显示任何错误的情况下直接编译。

我在 next.js 文档中读到 email 的有效负载必须有 2 个条目,即 CSRF 令牌和 email 地址。 我可以在浏览器工具中看到生成了 CSRF 令牌。 我还可以在网络选项卡中看到有效负载显示 email 地址,但 CSRF 令牌在提交时为空白。

提前感谢您对此提供的任何帮助。 Go 对我来说很容易,因为我是一个新的编码员!

好的,问题出在我的 getServerSideProps 上……

前:

export async function getServerSideProps(context) {
  const csrfToken = await getCsrfToken(context)
  const providers = await getProviders(context)
  return {
    props: { csrfToken },
    props: { providers },
  }
}

后:

export async function getServerSideProps(context) {
  const csrfToken = await getCsrfToken(context)
  const providers = await getProviders(context)
  return {
    props: { csrfToken, providers },
  }
}

我注意到 csrfToken 没有被传递到 email 提交有效负载中。

对于未来的其他人......如果您在单击提交之前检查您的页面,则可以使用 chrome devtools,然后您可以单击网络并检查有效负载和 header。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM