6

I used Firebase for User Auth in my Next.js Application. I want to protect a user on the client-side. I used firebase firebaseui react-firebaseUI to implement Google Auth. How to secure a Route in the Client-side itself

  const uiConfig = {
    signInFlow: "popup",
    signInSuccessUrl: "/dashboard",
    signInOptions: [firebase.auth.GoogleAuthProvider.PROVIDER_ID],
  }

I want to protect the dashboard Route. Thanks in advance :)

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
aravind ks
  • 612
  • 7
  • 18
  • The solution to your question involves a lot of steps. First you need to setup the routing for which you have not shown any code. Then you can use `firebase.auth().onAuthStateChanged` to track if the user if signed in or not and route accordingly. – isAif Dec 30 '20 at 11:00
  • @isAif the accepted solution uses `firebase.auth().onAuthStateChanged` itself. Second, it's not "long" but is bare minimum for good practice in React. – Vinay Sharma Sep 09 '21 at 05:35
  • @VinaySharma neither I have said anything about solution being "long" nor about "good practices". My commented is regarding the question requiring additional information. – isAif Sep 09 '21 at 10:42
  • @isAif I misinterpreted **lot of steps** as **long**, but either way the solution involves lot of steps to educate OP about a good practice to write protected routes in React. And the emphasis you've made on `firebase.auth().onAuthStateChanged` is already mentioned in the accepted solution itself. – Vinay Sharma Sep 09 '21 at 18:44

1 Answers1

9

Router:

At first you'll need to maintain a router which would contain all your public and protected routes.


import React from 'react';

import {
  Route,
  Switch,
  BrowserRouter,
} from 'react-router-dom';

import ProtectedRoute from './Protected';

import Foo from './Foo';
import Bar from './Bar';

const Routes = () => (
  <BrowserRouter>
    <Switch>
      // public route
      <Route exact path="/foo" component={Foo} />

      // protected route
      <ProtectedRoute exact path="/bar" component={Bar} />

      // if user hits a URL apart from the above ones, render a 404 component
      <Route path="*" component={NotFound} />
    </Switch>
  </BrowserRouter>
);

export default Routes;

Protected Route:

This is the protect route which would handle if a user should be allowed to access a protect page on your app based on it's auth status.

import React from 'react';

import { useAuthStatus } from '../hooks';

import Spinner from '../Spinner';
import UnAuthorised from '../UnAuthorised';

const ProtectedRoute = ({ component: Component }) => {
  // a custom hook to keep track of user's auth status
  const { loggedIn, checkingStatus } = useAuthStatus();

  return (
    <>
      {
        // display a spinner while auth status being checked
        checkingStatus
          ? <Spinner />
          : loggedIn
            // if user is logged in, grant the access to the route
            // note: in this example component is Bar
            ? <Component />
            // else render an unauthorised component
            // stating the reason why it cannot access the route
            : <UnAuthorised />
      }
    </>
  );
};

export default ProtectedRoute;

Firebase Auth Status:

Well, this is the custom hook to keep track of user logging in and logging out.


import { useEffect, useState } from 'react';

import { firebase } from '../config';

export const useAuthListener = (): void => {
  // assume user to be logged out
  const [loggedIn, setLoggedIn] = useState(false);

  // keep track to display a spinner while auth status is being checked
  const [checkingStatus, setCheckingStatus] = useState(true);

  useEffect(() => {
    // auth listener to keep track of user signing in and out
    firebase.auth().onAuthStateChanged((user) => {
      if (user) {
        setLoggedIn(true);
      }

      setCheckingStatus(false);
    });
  }, []);

  return { loggedIn, checkingStatus };
};

Dharman
  • 30,962
  • 25
  • 85
  • 135
Vinay Sharma
  • 3,291
  • 4
  • 30
  • 66