Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firebase Auth - createUserWithEmailAndPassword() - prevent login until email is verified

Tags:

I wish to create a user account in Firebase Auth using createUserWithEmailAndPassword() - without logging in the user. I wish for the user to verify the email address first. Signing in the user directly causes a lot of unwanted side effects.

The /signup page has the following code - I wish for the user to stay on the /signup page after registration to be able to see the registration message.

firebase.auth().createUserWithEmailAndPassword(data.email, data.password)
.then((user)=> {
  //Send email verification link
  user.sendEmailVerification()
  //Show message - "Your account was created - please verify using link in email"
  handleStatusMessage(AUTH_SUCCESS)
})
.catch((error)=>{...})

The app.js has the following login and redirect handler

//handle login and redirect
firebase.auth().onAuthStateChanged((user) => {
  if (user) {
    if(!user.emailVerified){
      //Exit if email is not verified
      console.log('auth.js exit')
      //Line 7
    }
    store.dispatch(setInitialStore()).then(() => {
      renderApp()
      //Brings user to start page
      if (history.location.pathname === '/login') {
        history.push('/start')
      }
    })
} else {
  renderApp()
  //Brings user to /login or /verifyEmail page when logged out
  if(!history.location.pathname.includes('/verifyEmail')){
    history.push('/login')
  }  
}

My problems are:

  1. The user gets redirected after successful signup unless I cancel execution on line 7

  2. If I cancel execution on line 7, the user gets stuck when moving away from /signup

  3. Logging out the user causes the onAuthStateChanged() to trigger twice - redirecting the user

How can I keep the user on the /signup page after successful account creation while still allowing the user to navigate to the /login /verifyEmail location? Preferably in logged out state.

like image 967
Kermit Avatar asked Sep 02 '19 21:09

Kermit


2 Answers

What I ended up doing was adding checks for when the user was logged in and logged out during signup.

signupPage.js

firebase.auth().createUserWithEmailAndPassword(data.email, data.password)
.then((user)=> {
  //Login is triggered --> line 4 in app.js
  user.sendEmailVerification() //Send email verification
  handleStatusMessage(AUTH_SUCCESS) //Show success message
  firebase.auth().signOut() //Logout is triggered --> line 16 in app.js
})
.catch((error)=>{ ... }

app.js

//handle login and redirect
firebase.auth().onAuthStateChanged((user) => {
  if (user) {
    //** line 4 ** EXIT if logged in from /signup
    if(!isEmailVerified && history.location.pathname.includes('/signup')){
      return
    }
    store.dispatch(setInitialStore()).then(() => {
      renderApp()
      //Brings user to start page
      if (history.location.pathname === '/login') {
        history.push('/start')
      }
    })
} else {
  //** line 16 ** EXIT if logged out from /signup
  if(history.location.pathname.includes('/signup')){
    return
  }
  renderApp()
  //Brings user to /login or /verifyEmail page when logged out
  if(!history.location.pathname.includes('/verifyEmail')){
    history.push('/login')
  }  
}

I really wish there was a option for createUserWithEmailAndPassword() to be able to automatically send the email verification email and not logging in the user to avoid this kind of cat-and-mouse game code. :)

A separate method along the lines of createUserWithEmailAndPasswordEmailVerificationRequired() that automatically sends the email link and does not sign in the user would also work ;)

like image 169
Kermit Avatar answered Sep 19 '22 12:09

Kermit


The Firebase Auth function createUserWithEmailAndPassword automatically signs in users upon successful account creation (which does not require email verification).

If you need to verify email addresses for new user sign-ups without automatic sign-in, then an alternative is Email Link Authentication.

You can use Firebase Authentication to sign in a user by sending them an email containing a link, which they can click to sign in. In the process, the user's email address is also verified.

There are numerous benefits to signing in by email:

  • Low friction sign-up and sign-in.
  • Lower risk of password reuse across applications, which can undermine security of even well-selected passwords.
  • The ability to authenticate a user while also verifying that the user is the legitimate owner of an email address.
  • A user only needs an accessible email account to sign in. No ownership of a phone number or social media account is required.
  • A user can sign in securely without the need to provide (or remember) a password, which can be cumbersome on a mobile device.
  • An existing user who previously signed in with an email identifier (password or federated) can be upgraded to sign in with just the email. For example, a user who has forgotten their password can still sign in without needing to reset their password.

After users successfully created accounts via email link authentication, you could provide the option to create a password and link to the existing account.

like image 38
Christopher Peisert Avatar answered Sep 16 '22 12:09

Christopher Peisert