javascript - Firebase 使用电子邮件链接登录并在不同设备上进行验证
问题描述
我创建了一个反应 js Web 应用程序,用户需要在其中登录。我使用了 Firebase 电子邮件无密码登录选项。单击发送链接按钮后,将发送一封包含该链接的电子邮件。现在点击链接,用户被重定向到另一个页面,用户需要点击一个按钮来验证电子邮件 ID。
如果用户使用相同的设备发送链接并进行验证,这可以正常工作。
但是,如果用户从设备 A发送链接并使用设备 B进行验证,则它不起作用
如何实现多设备登录功能。
- 从设备 A 发送链接
- 从设备 B 验证
- 刷新设备A中的页面并自动登录。
发送电子邮件链接和验证帐户位于 2 个不同的文件中以继续流程
电子邮件.js
import React, {useEffect, useState} from 'react'
import Modal from "react-modal";
import {Fade, Zoom} from "react-reveal";
import {sendemail} from "../../../backend/FirebaseEmail";
function Email() {
const [email, setEmail] = useState('')
const [sendingEmail, setSendingEmail] = useState(false)
const [emailSent, setEmailSent] = useState(false)
const customStyles = {
content: {
top: "50%",
left: "50%",
right: "auto",
bottom: "auto",
marginRight: "-50%",
transform: "translate(-50%, -50%)",
borderRadius: "15px",
border: "1.2px solid black",
},
};
const sendLink = (event) => {
setSendingEmail(true)
event.preventDefault();
sendemail(email).then((value) => {
setSendingEmail(true)
setEmailSent(true)
}).catch((error) => {
alert(error.message);
});
}
return (
<div>
<input type="email" placeholder="Email" value={email} onChange={e => setEmail(e.target.value)}/>
<button onClick={(e) => sendLink(e)}>{sendingEmail ? (
<i className="fa fa-spinner fa-spin"></i>) : ('Send link')}</button>
<Modal isOpen={emailSent} style={customStyles}>
<Fade>
<div className="email_sent_modal">
<Zoom><i className="fas fa-check check"></i></Zoom>
<h5>A Link has been sent to your E-mail Id.<br/>
Please click on the link to <b>verify</b></h5>
</div>
</Fade>
</Modal>
</div>
)
}
export default Email
发送邮件.js
import {auth} from '../../../firebasesetup'
export const sendemail = (email) => {
return new Promise((resolve, reject) => {
var actionCodeSettings = {
url: process.env.REACT_APP_PUBLIC_URL + 'verify',
handleCodeInApp: true
};
if (auth.currentUser === null) {
auth.sendSignInLinkToEmail(email, actionCodeSettings)
.then(function () {
resolve(true)
window.localStorage.setItem('emailForSignIn', email);
})
.catch(function (error) {
// Some error occurred, you can inspect the code: error.code
reject(false)
alert(error)
});
} else if (auth.currentUser.emailVerified) {
window.location.replace(process.env.REACT_APP_PUBLIC_URL);
//console.log(auth.currentUser)
}
})
}
verify.js(验证仅在同一设备上完全正常)
import React, {useState} from 'react'
import Modal from "react-modal";
import {Fade, Zoom} from "react-reveal";
import {auth} from '../../../firebasesetup'
function Verify() {
const [isVerifying, setisVerifying] = useState(false)
const [isverified, setisverified] = useState(false)
const customStyles = {
content: {
top: "50%",
left: "50%",
right: "auto",
bottom: "auto",
marginRight: "-50%",
transform: "translate(-50%, -50%)",
borderRadius: "15px",
border: "1.2px solid black",
},
};
const verify = () => {
setisVerifying(true)
if (auth.isSignInWithEmailLink(window.location.href)) {
var email = window.localStorage.getItem('emailForSignIn');
if (!email) {
email = window.prompt('Please provide your email for confirmation');
}
auth.signInWithEmailLink(email, window.location.href)
.then(function (result) {
var user = auth.currentUser;
user.updateProfile({
displayName: email
}).then(function () {
setisverified(true)
}).catch(function (error) {
alert(error)
});
window.localStorage.removeItem('emailForSignIn');
})
.catch(function (error) {
alert(error)
});
}
}
const close = () => {
window.location.replace(process.env.REACT_APP_PUBLIC_URL);
}
return (
<div>
<button onClick={verify}>
{isVerifying ? (
<i className="fa fa-spinner fa-spin"></i>) : ('Click to verify')}</button>
<Modal isOpen={isverified} style={customStyles}>
<Fade>
<div className="email_sent_modal">
<Zoom><i className="fas fa-check check"></i></Zoom>
<h5>Your account is successfully verified</h5>
<button style={{borderRadius: "10px"}} onClick={close}>
Done
</button>
</div>
</Fade>
</Modal>
</div>
)
}
export default Verify
解决方案
推荐阅读
- bash - 如何在 bash 脚本中使用动态选项/参数执行 cmd
- java - Spring Flux(或 Java Stream)合并为左连接
- sql-server - 如何在 SQL Server 中动态创建表?
- c - 在另一个函数中分配内存的变量
- amazon-web-services - 将静态 IP 分配给容器或无服务器解决方案
- mongodb - bindIP 不允许 IP 地址范围
- android - Firebase 实时数据库不保存包含列表或地图属性的 POJO
- json - VBA解析json并循环不同的对象
- c# - 使用SqlbulkcopycolumnMapping将数据从datatable复制到sql数据库
- image - Flutter Navigation 和同时对 dispose() 的要求