Este guia é um complemento de Como configurar a autenticação do Firebase com um aplicativo da Web React . Na introdução desse guia, observei que o Firebase oferece outros esquemas de autenticação além da autenticação básica por e-mail/senha. Uma dessas alternativas é a autenticação sem senha .
A autenticação sem senha é uma opção atraente na construção de aplicativos. Ele simplifica a experiência do usuário, pois seus usuários não precisam se lembrar de suas senhas e, portanto, também nunca precisam se preocupar em perdê-las. Também facilita a experiência de desenvolvimento, pois não há necessidade de projetar nenhuma captura de senha ou lógica de gerenciamento.
Neste guia, você criará um fluxo de trabalho simples de Login/Confirmação/Perfil/Logout que implementa a autenticação sem senha do Firebase.
O Google define vários limites do Firebase Authentication. Se você estiver usando o plano Spark gratuito, observe que você estará limitado a 5 e-mails com links de login por dia. Embora o plano Spark possa ser suficiente para fins de teste, você precisará atualizar para o plano Blaze pré-pago para ultrapassar esse limite.
Ao longo deste guia, irei me referir ao guia Como configurar o Firebase Authentication com um aplicativo Web React como o guia de pré-requisito e o projeto associado como o projeto de pré-requisito .
Para completar este guia, você precisará ter:
No guia de pré-requisitos, você criou um novo projeto do Firebase para autenticação básica de e-mail/senha. Agora, você habilitará o mesmo projeto para autenticação sem senha. Faça login em sua conta do Firebase e clique em Ir para o console .
Clique no seu projeto de autenticação listado no painel de projetos do Firebase. Este guia usa o nome do projeto my-auth-test
.
Clique em autenticação no menu do painel esquerdo.
Clique na guia Método de login na janela principal.
Do seu trabalho no guia de pré-requisitos, a tabela Provedores de login já deve exibir Email/Senha na coluna Provedores com um status Habilitado . Clique no ícone de lápis para abrir o painel de configuração do provedor de e-mail/senha .
Clique no botão de alternância para ativar o link E-mail (login sem senha) .
Clique em Salvar .
Seu projeto do Firebase agora está configurado para oferecer suporte à autenticação sem senha.
Crie um novo projeto React usando o nome do aplicativo desejado. Este guia usa passwordless-auth
.
npx create-react-app passwordless-auth
Este guia requer a instalação de 3 pacotes Node.js:
Instale cada um dos três pacotes acima via npm
:
npm install firebase
npm install react-router-dom
npm install bootstrap
firebase.js
do projeto de pré-requisito No projeto de pré-requisito, você criou um arquivo firebase.js
que usa os dados de configuração do projeto do Firebase para criar uma instância do serviço Firebase Authentication. Seu arquivo firebase.js
deve ter a seguinte estrutura com os valores de configuração do projeto Firebase:
import { initializeApp } from "firebase/app"; import { getAuth } from "firebase/auth"; const firebaseConfig = { apiKey: "AIzaSyDiUlY68W9Li_0EIkmdGdzD7nvqCT9kHnY", authDomain: "my-auth-test-fbd48.firebaseapp.com", projectId: "my-auth-test-fbd48", storageBucket: "my-auth-test-fbd48.appspot.com", messagingSenderId: "1078604952662", appId: "1:1078604952662:web:5d0b908439cfb5684ab7f7" } const app = initializeApp(firebaseConfig); const auth = getAuth(app); export { auth }
Copie firebase.js
para a nova pasta do projeto React.
Se você precisar revisar a configuração do seu projeto Firebase, clique no ícone de engrenagem próximo a Visão geral do projeto no menu do painel esquerdo. A guia Geral já deve estar selecionada. Role para baixo até a seção Seus aplicativos que contém o painel Aplicativos da Web . A opção npm no painel de aplicativos da Web já deve estar selecionada. Os valores de configuração do seu projeto serão listados no bloco de código exibido.
O aplicativo React consistirá em 5 componentes: App
, Layout
, Login
, Confirm
e Profile
.
App
App
define a estrutura geral do aplicativo, incluindo roteamento. Layout
Layout
especifica a marcação do aplicativo que permanece consistente em todas as rotas. Login
Confirm
Confirm
quando clica em um link de login. Profile
Profile
após confirmar seu endereço de e-mail.Profile
para sair de sua conta. O diretório src
final conterá os seguintes arquivos:
src |__ index.js |__ firebase.js // Copied from prerequisite project in Step 3. |__ App.js |__ Layout.jsx |__ Login.jsx |__ Confirm.jsx |__ Profile.jsx
reportWebVitals.js
setupTests.js
logo.svg
index.css
App.css
App.test.js
Copie index.js
do projeto de pré-requisito para a nova pasta do projeto. Este guia usa o mesmo arquivo. Se você precisar reconstruir index.js
, consulte a Etapa 5b.2 do guia de pré-requisitos ou copie o bloco de código abaixo.
Copie Layout.jsx
do projeto de pré-requisito para a nova pasta do projeto. Este guia usa o mesmo arquivo. Se você precisar reconstruir Layout.jsx
, consulte a Etapa 5d do guia de pré-requisitos ou copie o bloco de código abaixo. Opcionalmente, você pode atualizar o texto do projeto na tag <p>
de Layout.jsx
para React With Firebase Passwordless Authentication
ou qualquer título de sua preferência.
Seus arquivos index.js
e Layout.jsx
devem ser os seguintes:
// index.js import React from 'react'; import ReactDOM from 'react-dom/client'; import App from './App'; import "bootstrap/dist/css/bootstrap.min.css"; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <React.StrictMode> <App /> </React.StrictMode> );
// Layout.jsx import { Outlet } from "react-router-dom"; const Layout = () => { return( <div className = "container-fluid"> <div className = "row justify-content-center mt-3"> <div className = "col-md-4 text-center"> <p className = "lead">React With Firebase Passwordless Authentication</p> </div> <Outlet /> </div> </div> ) } export default Layout
App.js
O arquivo App.js
é basicamente o mesmo do projeto de pré-requisito, com alterações em apenas duas linhas. Para facilitar a construção do arquivo, copie App.js
do projeto de pré-requisito para a nova pasta do projeto.
Exclua a seguinte linha import
do arquivo e substitua-a conforme mostrado abaixo:
// Delete this line: import Signup from "./Signup";
// Replace it with: import Confirm from "./Confirm";
Exclua o seguinte <Route>
do arquivo e substitua-o conforme mostrado abaixo:
// Delete this line: <Route path = "/signup" element = { <Signup></Signup> } ></Route>
// Replace it with: <Route path = "/confirm" element = { <Confirm></Confirm> } ></Route>
Salve App.js
O arquivo completo agora deve ser o seguinte:
import Layout from "./Layout"; import Login from "./Login"; import Confirm from "./Confirm"; import Profile from "./Profile"; import { BrowserRouter, Routes, Route } from "react-router-dom"; const App = () => { return ( <BrowserRouter> <Routes> <Route path = "/" element = { <Layout></Layout> }> <Route index element = { <Login></Login> }></Route> <Route path = "/confirm" element = { <Confirm></Confirm> } ></Route> <Route path = "/profile" element = { <Profile></Profile> } ></Route> </Route> </Routes> </BrowserRouter> ) } export default App
Observe que o componente Login
é mais uma vez a rota inicial do aplicativo, assim como acontecia com o projeto de pré-requisito.
Login.jsx
No caso de autenticação sem senha, obviamente você não precisa incluir um campo de senha, nem gerenciar o estado para entrada de senha. Assim, o formulário de login só precisa capturar o endereço de e-mail do usuário.
Crie um novo arquivo Login.jsx
no diretório src
.
Adicione o seguinte código:
import { useState } from "react"; import { auth } from "./firebase"; import { sendSignInLinkToEmail } from "firebase/auth"; const Login = () => { const [email, setEmail] = useState(""); const [notice, setNotice] = useState(""); const actionCodeSettings = { url: "http://localhost:3000/confirm", handleCodeInApp: true } const callSendSignInLinkToEmail = (e) => { e.preventDefault(); sendSignInLinkToEmail(auth, email, actionCodeSettings) .then(() => { setNotice("An email was sent to your email address. Click the link in the email to login."); }) .catch((error) => { setNotice("An error occurred when sending a login link to your email address: ", error.name); }) } return( <div className = "container"> <div className = "row justify-content-center"> <form className = "col-md-4 mt-3 pt-3 pb-3"> { "" !== notice && <div className = "alert alert-warning" role = "alert"> { notice } </div> } <div className = "form-floating mb-3"> <input type = "email" className = "form-control" id = "exampleInputEmail" placeholder = "[email protected]" value = { email } onChange = { (e) => setEmail(e.target.value) }></input> <label htmlFor = "exampleInputEmail" className = "form-label">Email address</label> </div> <div className = "d-grid"> <button type = "submit" className = "btn btn-primary pt-3 pb-3" onClick = {(e) => callSendSignInLinkToEmail(e)}>Submit</button> </div> </form> </div> </div> ) }
Login.jsx
.
Ao capturar o endereço de e-mail do usuário, o formulário Login.jsx
envia um e-mail com um link de login para seu endereço por meio do método sendSignInLinkToEmail
do Firebase. Se for bem-sucedido, o usuário será notificado de que o e-mail foi enviado. Observe que o objeto actionCodeSettings
é passado como um parâmetro para o método sendSignInLinkToEmail
e inclui a URL para a qual o usuário será roteado quando clicar no link de login enviado por e-mail. Nesse caso, o URL é mapeado para a rota /confirm
especificada em App.js
.
Confirm.jsx
O método signInWithEmailLink
do Firebase é usado para fazer login em um usuário que clicou em um link de login. Como você verá a seguir, o método usa um parâmetro email
, e o valor de email
deve corresponder ao endereço de email que o usuário usou ao fazer login por meio do formulário de login. Confirm.jsx
apresenta ao usuário um formulário para confirmar seu endereço de e-mail e, posteriormente, tenta fazer login do usuário.
Crie um novo arquivo Confirm.jsx
no diretório src
.
Adicione o seguinte código:
import { useState } from "react"; import { auth } from "./firebase"; import { isSignInWithEmailLink, signInWithEmailLink } from "firebase/auth"; import { useNavigate } from "react-router-dom"; const Confirm = () => { const navigate = useNavigate(); const [email, setEmail] = useState(""); const [notice, setNotice] = useState(""); const callSignInWithEmailLink = (e) => { e.preventDefault(); if (isSignInWithEmailLink(auth, window.location.href)) { signInWithEmailLink(auth, email, window.location.href) .then(() => { navigate("/profile"); }) .catch((error) => { setNotice("An occurred during sign in: ", error.name); }) } } return( <div className = "container"> <div className = "row justify-content-center"> <form className = "col-md-4 mt-3 pt-3 pb-3"> { "" !== notice && <div className = "alert alert-warning" role = "alert"> { notice } </div> } <div className = "form-floating mb-3"> <input type = "email" className = "form-control" id = "exampleConfirmEmail" placeholder = "[email protected]" value = { email } onChange = { (e) => setEmail(e.target.value) }></input> <label htmlFor = "exampleConfirmEmail" className = "form-label">Please confirm your email address</label> </div> <div className = "d-grid"> <button type = "submit" className = "btn btn-primary pt-3 pb-3" onClick = {(e) => callSignInWithEmailLink(e)}>Confirm</button> </div> </form> </div> </div> ) } export default Confirm
Confirm.jsx
.
O método isSignInWithEmailLink
primeiro verifica se o link de login que o usuário está usando é válido. Se for, o método signInWithEmailLink
será chamado para conectar o usuário. Para reiterar, o valor email
passado para o método signInWithEmailLink
deve corresponder ao endereço de email que o usuário usou no formulário de login. Observe que se o usuário for um novo usuário (ou seja, é a primeira vez que faz login), o Firebase criará automaticamente o usuário no armazenamento do Firebase Authentication. Este é outro exemplo da experiência simplificada oferecida pela autenticação sem senha: a criação de contas para novos usuários é feita automaticamente.
Profile.jsx
O componente final que você construirá é Profile.jsx
. Os usuários são roteados para esse componente quando fazem login com êxito por meio de Confirm.jsx
. A rota dá as boas-vindas ao usuário com seu endereço de e-mail e fornece um botão para sair. Após o logout, o usuário é roteado de volta para o componente Login
.
Crie um novo arquivo Profile.jsx
no diretório src
.
Adicione o seguinte código:
import { auth } from "./firebase"; import { signOut } from "firebase/auth"; import { useNavigate } from "react-router-dom"; const Profile = () => { const navigate = useNavigate(); const logoutUser = async (e) => { e.preventDefault(); await signOut(auth); navigate("/"); } return( <div className = "container"> <div className = "row justify-content-center"> <div className = "col-md-4 text-center"> <p>Welcome <em className = "text-decoration-underline">{ auth.currentUser.email }</em>. You are logged in!</p> <div className = "d-grid gap-2"> <button type = "submit" className = "btn btn-primary pt-3 pb-3" onClick = {(e) => logoutUser(e)}>Logout</button> </div> </div> </div> </div> ) } export default Profile
Profile.jsx
.Inicie o aplicativo React:
npm start
locahost:3000
em seu navegador se ele não iniciar automaticamente. Você deverá ver o formulário Login
.
Digite o e-mail que deseja usar para fazer login e clique em Enviar . Se o envio for bem-sucedido, será exibida uma notificação informando que um e-mail com um link de login foi enviado para o seu endereço de e-mail.
Sign in to project-1078604952662
, onde a sequência numérica de 13 dígitos representa o messagingSenderId
do seu projeto Firebase (consulte a Etapa 3 deste guia). Na seção Opcional abaixo, explicarei como você pode modificar o nome do seu projeto Firebase para exibir um nome "amigável" nos e-mails de link de login. Por enquanto, abra o e-mail do link de login e clique no link de login. Você será direcionado para o formulário Confirm
.
Digite o endereço de e-mail que você usou ao fazer login no formulário Confirm
. Clique em Confirmar . Se a confirmação for bem-sucedida, você será direcionado para a página Profile
.
Clique no botão Sair na página Profile
para sair. Se a saída for bem-sucedida, você será direcionado de volta ao formulário Login
.
As etapas acima capturam o fluxo de trabalho do aplicativo.
Você pode alterar o nome do seu projeto para que os e-mails com links de login enviados pelo Firebase exibam um nome "amigável" em vez de, por exemplo, project-1078604952662
. Faça login em sua conta do Firebase e clique em Ir para o console .
A autenticação sem senha parece ser uma escolha cada vez mais popular entre os desenvolvedores de aplicativos, e isso é compreensível. Além da vantagem óbvia de eliminar a necessidade de gerenciamento de senhas, também não há necessidade de verificação de e-mail, pois o processo de envio do link de login é uma verificação por si só.
Tal como acontece com o projeto de pré-requisito, a implementação aqui é básica. Você pode considerar melhorias simples, como:
Bloquear/colocar domínios de endereços de e-mail específicos na lista negra (ou seja, domínios de e-mail de spam comuns).
Armazenar localmente o endereço de e-mail inserido pelo usuário na página Login
e verificar a existência do endereço de e-mail na página Confirm
. Com essa abordagem, se o usuário clicar em um link de login no mesmo dispositivo onde acessou a página Login
, ele não precisará inserir seu endereço de e-mail novamente na página Confirm
, pois ele será recuperado do armazenamento local. Isso proporciona uma experiência de usuário ainda mais tranquila.
Você pode aprender mais sobre o Firebase Passwordless Authentication na documentação oficial .