用户使用 next-auth 的电子邮件提供商注册时如何在 mongo 中存储其他字段

tom*_*eah 5 authentication mongodb jwt next.js next-auth

我创建了一个包含两个字段的登录表单

  • 用户可以选择他们的大学的字段
  • 用户可以输入他们的大学电子邮件地址的字段

我在后台使用 next-auth 的电子邮件提供商,因此当他们填写这两个字段并单击“注册”时,默认情况下会在我的 MongoDB“用户”集合中自动创建一个文档,如下所示

email: 'theuseremail@something.com',
emailVerified: '2022-07-16T11:54:06.848+00:00'
Run Code Online (Sandbox Code Playgroud)

用户会收到一封电子邮件,其中包含用于登录网站的魔术符号链接。

我的问题如下: 我希望不仅能够存储用户电子邮件,还能够存储他们在填写注册表时选择的大学。但在我的 MongoDB 中默认创建的对象只有“email”和“emailVerified”字段。我无法找到一种方法来捕获其他数据(例如用户选择的大学)以在数据库中创建用户。

有什么明显的方法可以让我失踪吗?我环顾四周,但找不到任何可行的例子!任何帮助表示赞赏。

这是我的pages/api/[...nextAuth].js 文件

import NextAuth from "next-auth"
import nodemailer from 'nodemailer'
import EmailProvider from 'next-auth/providers/email'
import { MongoDBAdapter } from "@next-auth/mongodb-adapter"
import clientPromise from "../../../utils/mongoClientPromise"

const THIRTY_DAYS = 30 * 24 * 60 * 60
const THIRTY_MINUTES = 30 * 60


export default NextAuth({
  secret: process.env.NEXTAUTH_SECRET,
  session: {
    strategy: 'jwt',
    maxAge: THIRTY_DAYS,
    updateAge: THIRTY_MINUTES
  },
  adapter: MongoDBAdapter(clientPromise),
  providers: [
    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,
      async sendVerificationRequest ({
        identifier: email,
        url,
        provider: { server, from }
      }) {
        const { host } = new URL(url)
        const transport = nodemailer.createTransport(server)
        await transport.sendMail({
          to: email,
          from,
          subject: `Sign in to ${host}`,
          text: text({ url, host }),
          html: html({ url, host, email })
        })
      }
    })
  ],
  pages: {
    signIn: '/login',
  }
})

function html ({ url, host, email }) {
  const escapedEmail = `${email.replace(/\./g, '​.')}`
  const escapedHost = `${host.replace(/\./g, '​.')}`
  // Your email template here
  return `
      <body>
        <h1>Your magic link! </h1>
        <h3>Your email is ${escapedEmail}</h3>
        <p>
          <a href="${url}">Sign in to ${escapedHost}</a>
      </body>
  `
}

// Fallback for non-HTML email clients
function text ({ url, host }) {
  return `Sign in to ${host}\n${url}\n\n`
}
Run Code Online (Sandbox Code Playgroud)

这是我在pages/login.tsx中的登录页面

import { Row, Col, Button, Input, Form, Space } from "antd";
import { useSession, signIn } from "next-auth/react";
import { getCsrfToken } from "next-auth/react"
import { useRouter } from 'next/router';
import { useState } from "react";
import UniversitySearchAndSelectDropdown from "../components/UniversitySearchAndSelectDropdown";
import data from '../mock_api_payload.json'


export default function LoginPage({ csrfToken }) {
    const navigate = useRouter();
    const { data: session } = useSession()
    const [selectedUniversityId, setSelectedUniversityId] = useState('');
    const [form] = Form.useForm();

    if (session) {
        navigate.push("/")
    }
    if (!session) {
        return (
        <>
            <Row justify="center" style={{marginTop: '2rem'}}>
                <Col>
                <form method="post" action="/api/auth/signin/email">
                    <input name="csrfToken" type="hidden" defaultValue={csrfToken} />
                    <Row justify="center">
                        <Col>
                            <Space direction="vertical">
                                <Input 
                                    placeholder="Enter your university email address" 
                                    type="email" 
                                    id="email" 
                                    name="email" 
                                />
                            </Space>
                        </Col>
                    </Row>
                    <Row justify="center" style={{marginTop: '1rem'}}>
                        <Col>
                            <Button 
                                htmlType="submit" 
                                shape="round"
                                type="primary"
                            >Sign in</Button>
                        </Col>
                    </Row>
                </form>
                </Col>
            </Row>
        </>
        )
    }
};

export async function getServerSideProps(context: any) {
    const csrfToken = await getCsrfToken(context)
    return {
      props: { csrfToken },
    }
}
Run Code Online (Sandbox Code Playgroud)

谢谢你!