Automatically send users to the login page upon page load if they are not authenticated using Nuxt and Firebase

I'm currently facing an issue with setting up navigation guards in my Nuxt application. The goal is to redirect users to the login screen if they are not authenticated using Firebase Authentication. While the router middleware successfully redirects users when they attempt to navigate, I noticed that it does not work on page load.

Upon further investigation, I realized that the middleware is not triggered on page load. I tried using a plugin to handle the redirect on page load, but unfortunately, it did not work as expected. Even calling router.push from within the plugin did not redirect the user.

Let me provide some context about my setup. The application is deployed directly to Firebase hosting as a Single Page Application (SPA) without Server-Side Rendering. I am utilizing the Nuxt-Firebase module along with Firebase Authentication service.

// nuxt.config.js

  target: "server", // server here works when I deploy to firebase, but I also tried static
  ssr: false,
  middleware: ["auth"],
  plugins: [
    "~/plugins/auth.js",
  ],
  modules: [
    [
      "@nuxtjs/firebase",
      {
        services: {
          auth: {
            initialize: {
              onAuthStateChangedMutation:
                "authData/ON_AUTH_STATE_CHANGED_MUTATION",
              onAuthStateChangedAction: "authData/ON_AUTH_STATE_CHANGED_ACTION",
              subscribeManually: false,
            },
          },
        },
      },
    ],
  ],
};

I attempted to address the issue with a custom plugin, however, the function handleLoggedOut seems to have no effect on page load.

// --- plugin to redirect user --- /plugins/auth.js   ---
export default function (context, inject) {
  const auth = {
    handleLoggedOut: () => {
      console.log("logout handled");
      context.redirect("/login");
    },
  };
  inject("auth", auth);
}

// --- store actions --- /store/authData.js  ---
  actions: {
    async ON_AUTH_STATE_CHANGED_ACTION(
      { commit, state, dispatch },
      { authUser, claims }
    ) {
      if (authUser) {
         // user logged in
      }
      else {
         // attempting to redirect here does not work
         this.$auth.handleLoggedOut()
      }
   }

As a newcomer to Nuxt, I have been struggling to find a solution to this particular issue. If anyone could provide assistance, I would be grateful. Thank you!

Answer №1

Your code looks good, but one improvement you can make is using the simple this.$fire.auth.signOut() instead of relying on the auth plugin.

For instance:

// --- store actions --- /store/authData.js ---

actions: {
    async signOut({ commit }, payload) {
        try {
           await this.$fire.auth.signOut();
           // To prevent NavigationDuplicated error, it's safe to remove the if block
           if (!payload) {
              this.$router.push('/login')
           }
           commit(ON_AUTH_STATE_CHANGED_MUTATION, { authUser: null})
        } catch(err) {
           console.log(err)
        }

    },
async ON_AUTH_STATE_CHANGED_ACTION(
      { commit, state, dispatch },
      { authUser, claims }
    ) {
      if (authUser) {
         // user logged in
      }
      else {
         // redirection doesn't work here
         return dispatch('signOut')
      }
   }

}

Answer №2

To tackle the issue of redirecting users to the login page upon loading, I found a solution by implementing the following logic within my authentication middleware:

export default function ({ redirect, store, route }) {
  // Implementing a redirection if the user is not logged in
  if (!store || !store.getters || !store.getters["authData/isLoggedIn"]) {
    window.onNuxtReady(() => {
      window.$nuxt.$router.push("/login");
    });
  }
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Vue2Leaflet does not seem to be able to place a custom icon on the map

I've attempted numerous examples, but all I get are broken images or default icons <l-marker v-for="marker in getFilteredVehicles" :lat-lng="marker.latLng" :key="marker.rtoNo" @click="o ...

Using Vue-cli 3.0 to configure options for pre-processor loaders across multiple files

When looking at the config in vue.config.js as per the info on the official documentation const fs = require('fs'); module.exports = { lintOnSave: false, css: { loaderOptions: { sass: { data: fs.readFileSync('src/sass ...

Best Way to Eliminate "#" Symbol from URL Address in UI-Router

My website URL is structured as follows: This is the index page where I utilize Angular UI-Router to navigate to different views, however, the URL retains the hash symbol (#) like this: Query: I am looking for a way to eliminate/remove the hash tag from ...

Resolving Problems with setInterval in jQuery Ajax Calls on Chrome

Seeking assistance in returning the value of a specific URL periodically using jQuery and setInterval. Below is my current code snippet: $("form").submit(function() { setInterval(function(){ $('#upload_progress').load(&ap ...

The React Js error message shows an 'Uncaught (in promise)' TypeError that prevents reading an undefined property

Struggling with passing the response from an Ajax request to another function in React. Although I am able to receive the response, I cannot pass it to { this.showBattersData(data); } where I need to render the DOM. It's clear that something is missin ...

Providing real-time results as numbers are added together

I need assistance in calculating a price inclusive of VAT based on a user-entered VAT rate. Is it possible to show the result in an input box dynamically as the user inputs the VAT rate and price, without requiring them to click a button or resubmit the fo ...

Capture a snapshot with Protractor using the Jasmine2 Screenshot Reporter

The Protractor configuration file includes 2 custom reporting options: one for logging and the other is the protractor-jasmine2-screenshot-reporter. However, only a blank white screen is displayed when generating a screenshot png. Below is the code snippet ...

Tally up various figures in all tables

I am dealing with a dynamic table generated from a PHP loop. Below is an example of the table structure extracted from the browser source code: <table class="table"> ... (table content) </table> <table class="table"> ... (t ...

Strategies for transferring information to a different component in a React application

Building a movie site where users can search for films, click on a card, and access more details about the film is proving challenging. The problem lies in transferring the film details to the dedicated details page once the user clicks on the card. An onc ...

Add a <div> element to a webpage in a random location every time the page is refreshed

I have a variety of 2 types of <div>s displayed on a single page. Collection 1 consists of: <div class="feature">content 1</div> <div class="feature">content 2</div> ...and so forth. Collection 2 consists of: <div class ...

Error in Heroku deployment - Express and React app displaying a white screen

I am encountering a challenging situation as I attempt to understand the issue at hand. Following the deployment of my React/Express application on Heroku, the build and deployment proceed without errors, but the React frontend appears blank. The browser ...

Steps to deactivate a JavaScript function once the page has undergone a Page.IsPostBack event

My current setup involves a simple div with the display set to none. Upon page load, I use $("#MyDiv").show(); to display the div after a delay, allowing users to enter information into the form and submit it using an asp.net button. After submitting the ...

Having issues with my AngularJS application not updating as expected

After creating a custom service to store all search parameters, I can easily access them from any part of my code. This ensures that the search parameters are always accurate. Below is the definition of the custom service: App.factory('filterService& ...

Having difficulties grasping the concept of how to communicate effectively with my MySQL database

Apologies in advance for asking a question that may have been answered elsewhere, but I've been struggling for hours to transfer the information into my own program. Despite my attempts, I always encounter the same obstacles. So, I decided it would be ...

Guide on setting an attribute value with JavaScriptExecutor in Selenium WebDriver

I am attempting to set an attribute value for all instances of the same type of <img> tag on My website, for example: <img src="images/temp/advertisement.png"> and I want to set style="display: none" so that I can hide them. I have tried the ...

Using Webpack 4 to import SCSS files with aliases

Currently, I am running a node script that is using webpack to bundle multiple folders for various installations on our server. MiniCssExtractPlugin.loader, { loader: 'css-loader', options: { ...

What is the best way to add values to a JavaScript object using jQuery or plain JavaScript?

I have an object here and I am looking to dynamically insert values into it. var mergTr={}; //object for(dd in dispID) { var dataID=displayObj[dispID[dd]]; if(dataObj[dataID]) { var flag=0; var v ...

Issue with Vue method not providing expected output

As I dive into the world of Vue, I find myself facing a peculiar issue with a method that should return a string to be displayed within a <span>. While I can successfully retrieve the correct value through console.log, it seems to evade passing into ...

What is the process for transferring a JSON data object to the server with JavaScript XMLHttpRequest?

When I attempt to send an XMLHttpRequest to a PHP server, I am encountering difficulties in getting the $_POST or $_REQUEST object to be filled with the data I am sending using JavaScript: var r = new XMLHttpRequest; r.open("POST", "http://url.com", true ...

Encountering an issue while fetching information from a JSON file using JavaScript

I am encountering an Uncaught SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data let mydata = JSON.parse("file.json"); console.log(myJSON) Here is a sample of the JSON file's data: [[1,1,0,1,1,0,0,0,1,1,1,1,1, ...