Firebase使用电子邮件链接登录并在其他设备上进行验证

时间:2020-10-05 09:30:16

标签: javascript reactjs firebase firebase-authentication

我创建了一个React js Web应用程序,用户需要在其中登录。我使用了Firebase电子邮件无密码登录选项。点击发送链接按钮后,将发送包含该链接的电子邮件。 现在,单击链接后,用户将被重定向到另一个页面,在该页面中,用户需要单击按钮来验证电子邮件ID。
如果用户使用同一设备发送链接并进行验证,则此方法正常。

但是,如果用户从设备A 发送链接并通过设备B

进行验证,则无法正常工作

如何通过多个设备实现登录功能。

  1. 从设备A发送链接
  2. 从设备B验证
  3. 刷新设备A中的页面并自动登录。

发送电子邮件链接和验证帐户位于2个不同的文件中以继续进行操作

Email.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

Sendemail.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

0 个答案:

没有答案