我正在使用 firebase 在 next js 中构建邀请注册。这是我想要实现的流程:
注意:此链接应该会在一天内过期。一旦使用该邀请链接进行注册,它就应该过期。 技术:next js/node 和 firebase
我使用了 sendEmailverific action(),但是当我使用它时,我无法从该 firebase 链接的 oobcode 获取用户电子邮件。这样我就可以使用用户输入的电子邮件和密码在 firebase 中创建新用户。
在 Next.js 中创建 API 路由来处理邀请电子邮件的发送。
// pages/api/sendInvitation.js
import { getAuth } from 'firebase-admin/auth';
import { initializeApp, applicationDefault, cert } from 'firebase-admin/app';
const serviceAccount = require('../../path/to/serviceAccountKey.json');
initializeApp({
credential: cert(serviceAccount)
});
export default async (req, res) => {
const { email } = req.body;
if (!email) {
return res.status(400).json({ error: 'Email is required' });
}
try {
const link = await getAuth().generateSignInWithEmailLink(email, {
url: 'http://yourdomain.com/completeSignup', // URL to redirect to after email verification
handleCodeInApp: true
});
// Send email logic here (using nodemailer, SendGrid, etc.)
res.status(200).json({ message: 'Invitation sent' });
} catch (error) {
res.status(500).json({ error: error.message });
}
};
在 Next.js 中创建一个页面,供用户在单击邀请链接后设置密码。
// pages/completeSignup.js
import { useState } from 'react';
import { getAuth, confirmSignInWithEmailLink, createUserWithEmailAndPassword } from 'firebase/auth';
import { initializeApp } from 'firebase/app';
const firebaseConfig = {
// your firebase config
};
const app = initializeApp(firebaseConfig);
const auth = getAuth(app);
export default function CompleteSignup() {
const [password, setPassword] = useState('');
const [message, setMessage] = useState('');
const handleSubmit = async (event) => {
event.preventDefault();
try {
const email = window.localStorage.getItem('emailForSignIn');
if (!email) {
throw new Error('Email not found');
}
if (confirmSignInWithEmailLink(auth, email, window.location.href)) {
await createUserWithEmailAndPassword(auth, email, password);
setMessage('User created successfully');
}
} catch (error) {
setMessage(`Error: ${error.message}`);
}
};
return (
<div>
<h1>Complete Signup</h1>
<form onSubmit={handleSubmit}>
<input
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
placeholder="Set Password"
required
/>
<button type="submit">Submit</button>
</form>
<p>{message}</p>
</div>
);
}
为确保链接在一天后过期并在使用后无效,您可以利用 Firebase 身份验证的内置功能。
generateSignInWithEmailLink
方法已经处理过期和一次性使用。唯一的额外步骤是确保在生成链接时临时存储电子邮件并在用户完成注册后清除电子邮件。
在
sendInvitation
API 路由中集成您首选的电子邮件发送服务(如 nodemailer、SendGrid 等)以发送生成的链接。
import nodemailer from 'nodemailer';
// Assuming you have the email link generation code here
const transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: '[email protected]',
pass: 'your-email-password'
}
});
const mailOptions = {
from: '[email protected]',
to: email,
subject: 'Complete your signup',
html: `<p>Click <a href="${link}">here</a> to complete your signup.</p>`
};
transporter.sendMail(mailOptions, (error, info) => {
if (error) {
return console.log(error);
}
console.log('Email sent: ' + info.response);
});
用户完成注册后请务必清除本地存储:
if (confirmSignInWithEmailLink(auth, email, window.location.href)) {
await createUserWithEmailAndPassword(auth, email, password);
window.localStorage.removeItem('emailForSignIn'); // Clear email from local storage
setMessage('User created successfully');
}