Securing paths in NuxtJS

Hey there! I'm just getting started with nuxt and have set up the following routes:

/home

/dashboard

/login

My goal is to secure the /dashboard route only for users who are logged in and have a token stored in LocalStorage.

The simplest solution I came up with was to create a /middleware/auth.js file:

export default function () {
  if (!window.localStorage.getItem('token')) {
    window.location = '/login'
  }
}

and then include it in the /dashboard/index.vue component:

<script>
export default {
  middleware: 'auth',
}
</script>

Unfortunately, this approach doesn't seem to be working as intended. It seems like I can't access local storage within the middleware:

window is not defined

Can anyone offer some assistance?

Note: I won't be utilizing Vuex in this particular project.

Answer №1

Dealing with a similar issue, I recommend utilizing cookies instead of localStorage for a smoother experience.

Nuxt, an SSR wrapper, prioritizes fetching data from the server before resorting to the client side. As others have pointed out, middleware will first check the server implementation if it's the initial page load (including manual refresh or non-Nuxt/Vue router anchor links). Since LocalStorage is exclusive to the browser, any access attempts must be client-side. By storing token data as a cookie, Nuxt can easily access it through HTTP requests that include cookies on every page request.

To facilitate a cookie-based solution, leverage Nuxt's store using the actions hook nuxtServerInit (https://nuxtjs.org/guide/vuex-store#the-nuxtserverinit-action). This enables setting server-side states like the access token, automatically synchronized with the client-side store.

A convenient option is employing the universal-cookies package or creating a custom method to handle server-received or client-stored cookies conditionally.

store/index.js

import Cookies from 'universal-cookies'

export const state = () => ({
  token: null
})

export const actions = {
  nuxtServerInit ({ commit }, { req }) {
    const cookies = new Cookies(req.headers.cookie)
    const token = cookies.get('token')
    commit('SET_TOKEN', token);
  }
}

export const mutations = {
  SET_TOKEN: (state, token) => {
    state.token = token
  }
}

export const getters = {
  token: state => state.token
}

Your middleware can now access the token state from the store whether it originates from the server or client thanks to the provided Nuxt context object in all middleware methods. Don't forget about the universal redirect method available within context.

middleware/auth.js

export default function ({ store, redirect }) {
  if (!store.getters['token']) {
    redirect('/login')
  }
}

While this doesn't directly address localStorage compatibility, leveraging cookies aligns well with Nuxt's server-side focus and simplifies handling authorization/authentication requests.

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

Searching for an AngularJS and Bootstrap Dual Listbox Solution

I need a component like this to integrate into my project: I am hoping to add it using npm. However, I have tried some of the examples available but faced issues (encountered exceptions or only found bower instead of npm). The following are the examples ...

Failed jQuery AJAX request to database with no returned information

I'm really confused about where the issue lies :S The button triggers a function that passes the parameter "sex" and initiates an ajax call to ajax.php, where I execute a MySQL query to retrieve the results and populate different input boxes. When I ...

Having trouble retrieving json data from PHP page using jQuery $.ajax

Having trouble accessing this JSON data in JavaScript, as when I try to alert it the result comes back as undefined Below is the jQuery code snippet: $.ajax({ type: "POST", url: "frmMktHelpGridd.php", data: { labNo: secondElement ...

Can you explain the contrast between 'depict' and 'examine' when using Jest?

I am currently diving into the world of unit testing in Vue.js with Jest. One question that keeps popping up is when to use describe and when to use test ? TodoApp.vue Component : <template> <div> <h1>TodoApp Componenent</h1> ...

Whenever I attempt to input "hello world" in Vue, an error message always pops

Encountered the following issue : Component template must have only one root element. If you are using v-if on multiple elements, use v-else-if to chain them instead. Upon attempting : <template> <h1>Your Horoscope</h1> <h3& ...

Transforming JSON data into a visually appealing pie chart using highcharts

I'm having trouble loading my JSON string output into a highcharts pie chart category. The chart is not displaying properly. Here is the JSON string I am working with: var json = {"{\"name\":\"BillToMobile\"}":{"y":2.35},"{\ ...

Re-establishing the socket channel connection in a React application after a disconnection

There are several solutions to this issue, but none of them seem to be effective for me. The existing solutions are either outdated or do not meet my needs. I am facing a problem where I have a large amount of data being transferred from the server to the ...

Where should uploaded files be stored using ng-flow?

Initially, I am utilizing the ng-flow, which is an html5 file upload extension built on the angular.js framework. After uploading my files and logging the event in the console, I'm uncertain about where and how to store them. Below is my HTML code w ...

Alter the website link in an HTML file as well as in the corresponding CSS and JavaScript

Is it possible for JQuery to alter URLs within a CSS or Javascript resource before they are loaded into the browser, or even as they load in the browser? URLs typically point to resources such as images and fonts. I have been considering this idea becaus ...

What is the functionality behind a free hosting website?

Is anyone familiar with websites like Hostinghood, where users can create a subdomain and upload HTML, CSS, etc.? I'm curious about how they operate and how I can create a similar site. This is my first question here, so please respond instead of disl ...

What is the reason for the Pinia Persistedstate Plugin breaking when the statement "useUserStore(store)" is called in a Quasar boot file?

Currently, I am attempting to integrate the Pinia Persisted State Plugin with Pinia in my Quasar application (Vue 3 / TypeScript). Initially, everything functions correctly right out of the box. However, the persisted state ceases to operate when incorpo ...

What is the reason for jQuery displaying undefined when attempting to retrieve a custom data attribute using .prop()?

In my dynamic HTML generated by JavaScript, the following code snippet is included: $(".task-status").live("click", function () { alert("data-id using prop: " + $(this).prop("data-id")) alert("data-id using data: " + $(this).data("id")) ...

Guide on incorporating a JS file in a React application

I recently obtained a template for my website that includes the following JS file which is being called from my React component. !(function($) { "use strict"; // Hero typed if ($('.typed').length) { var typed_strings = $(&quo ...

Ways to verify multiple radio groups to ensure none have been left unchecked

Is there a more elegant solution to check if either "salad" or "side dish" is left unchecked after submission? I currently have a working approach, but it feels overly complex for such a simple task. This is my current method: function radiosChecker(){ l ...

Error occurred when sending form data while uploading a file

Upon trying to upload a file using the formData.append(key, value);, an error message is displayed in the value section: The argument of type 'unknown' cannot be assigned to a parameter of type 'string | Blob'. Type '{}' is ...

Sorry, but we couldn't complete your request: User verification unsuccessful: email must be provided

Every time I attempt to save a user's credentials to the mongo database, an error pops up saying: "User validation failed: email: Path email is required." I am clueless as to why this issue keeps happening. It only started occurring when I added the v ...

Guide on passing authorization header from Flask API to VueJS

I've been working on a login page that utilizes JWT for authorization. The backend authorization is functioning properly, but I am encountering an error when trying to authorize the page using axios from VueJS. The error message indicates "Missing aut ...

Leverage the power of i18n in both vuejs components and blade.php templates

Is it possible to use i18n in both blade.php and Vue.js views? I have set up a json file for i18n as shown below: export default { "en": { "menu": { "home":"Home", "example":"Example" } } } Using this i18 ...

Angular custom filter applied only when a button is clicked

I have recently started exploring angular custom filters and I am curious to know if there is a way to trigger the filters in an ng-repeat only upon clicking a button. Check out this example on jsfiddle : http://jsfiddle.net/toddmotto/53Xuk/ <div ...

next-images encountered an error during parsing: Unexpected character ''

Having trouble loading images dynamically with next-images: //Working <Image src={require(`../../images/exampleImage.jpg` )}/> However, I want to use a dynamic URL like this: //Not working <img src={require(`../../images/${image}.jpg` )}/> Th ...