简体   繁体   English

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

[英]Next auth email provider is not triggering

Next-Auth has been working great for me until i decided to create a custom signIn page.在我决定创建自定义登录页面之前,Next-Auth 一直对我很好。

I have google login working perfectly and i can see lots going on in the debugger around token generation and session creation with my adapter.我的谷歌登录工作完美,我可以看到调试器中围绕令牌生成和使用我的适配器创建 session 进行了很多工作。

However, when I try to sign in using email verification it just clears the email from the input box and then does nothing.但是,当我尝试使用 email 验证登录时,它只会从输入框中清除 email,然后什么也不做。 The Form is straight out of the next auth docs.该表单直接来自下一个身份验证文档。

I have triple checked the settings for my sendgrid apikey and they are all set correctly in my.env.local file.我已经三次检查了我的 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)

Here is my custom page...这是我的自定义页面...

"/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 },
  }
}

EDIT: Installed Dependencies编辑:安装的依赖项

"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",

EDIT: ENV SETTINGS编辑:环境设置

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)

Also set are the following...还设置了以下...

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

EDIT: "/pages/_app.js" - Added main app just in case the problem is being caused by the way I have wrapped my component.编辑:“/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

UPDATE: when the email address is entered and the submit is clicked i get the following change in the URL.更新:当输入 email 地址并单击提交时,我在 URL 中得到以下更改。

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

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

UPDATED 30.08.2022 - I can see in terminal the following... wait - compiling /_error (client and server)... However the event compiles straight after without any error being displayed.更新 30.08.2022 - 我可以在终端中看到以下内容......等待 - 编译 /_error(客户端和服务器)......但是事件在没有显示任何错误的情况下直接编译。

I read in the next.js docs that the payload for email must 2 entries, the CSRF token and the email address.我在 next.js 文档中读到 email 的有效负载必须有 2 个条目,即 CSRF 令牌和 email 地址。 I can see in the browser tools that the CSRF token is generated.我可以在浏览器工具中看到生成了 CSRF 令牌。 I can also see in the network tab that the payload shows the email address but the CSRF Token is blank on submission.我还可以在网络选项卡中看到有效负载显示 email 地址,但 CSRF 令牌在提交时为空白。

Thanks in advance for any help on this one.提前感谢您对此提供的任何帮助。 Go easy on me as I am a new coder! Go 对我来说很容易,因为我是一个新的编码员!

Ok so the problem was with my getServerSideProps...好的,问题出在我的 getServerSideProps 上……

BEFORE:前:

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

AFTER:后:

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

I noticed that the csrfToken was not being passed into the email submit payload.我注意到 csrfToken 没有被传递到 email 提交有效负载中。

For others in future...using chrome devtools if you inspect your page prior to clicking submit then you can click on network and check the payload and header.对于未来的其他人......如果您在单击提交之前检查您的页面,则可以使用 chrome devtools,然后您可以单击网络并检查有效负载和 header。

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

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