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

NextJs not processing Bootstrap form submissions

I’m struggling to figure out why my form isn’t submitting when I click the submit button. The backend seems fine because Postman successfully sends the information to the database. However, nothing happens when I try to submit the form. My tech stack ...

The React component designed to consistently render video frames onto a canvas is unfortunately incompatible with iOS devices

I'm facing an issue with my code snippet that is supposed to draw video frames on a canvas every 42 milliseconds. It's working perfectly on all platforms and browsers except for iOS. The video frames seem unable to be drawn on canvas in any brows ...

To enhance your React Class Component, make sure to utilize the withStyles feature when

This particular component is not set as a default export component. I am attempting to apply some styles to it but struggling to figure out how to encapsulate it in an HOC. Hence, the current issue where it does not recognize the classes variable. import ...

Eliminating the Skewed Appearance of Text in Input Fields Using CSS

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Customized Page Layout</title> <script src="https://c ...

Different ways to activate the system bell in Node.js

Currently, I have a custom nodejs script running for an extended period and I'm seeking a way to receive a notification once the script finishes its execution. Is there a method in nodejs that can be used to activate the "System Bell" alert? ...

Trouble with nested components not refreshing correctly within VueJs

I've just started working with Vue and I'm currently developing a forum-style application that allows nested comments. Within this structure, there are two main components: PostForum and Comment. The PostForum component consists of an input box f ...

Locate a jquery element that is within a parent element containing specific text

This is the format I currently have: <td width="270px"> <img class="bullet" border="0" valign="top" src="gray-bullet.gif"> this is the text </td> Can someone provide me with a query to specifically target the img element with the class ...

Set datatables to perform regex searches that specifically target the beginning of text

Here is my JavaScript code for using datatables, I want to have the search function only filter results that start with the specified keyword. For example, if I have [hello, hello_all, all_hello] and my search term is "hel", I should only get [hello, hel ...

Filtering function that works without specific knowledge of keys

I'm working on a JavaScript method to filter a list dynamically without knowing the specific key (s). I've made some progress, but I'm stuck and not sure how to proceed. The foreach loop I have isn't correct, but I used it for clarity. ...

VueJS: Preloading data prior to and following component initialization

VueJS is a new technology for me, and I'm currently working on a component that needs to retrieve data from an API before loading the corresponding route. The component should only load once the data is fetched. Additionally, after the component is cr ...

Exclude certain packages from being processed in webpack

After setting up my webpack configuration, everything was running smoothly with the specified packages in the package.json: { "peerDependencies": { "react": "16.13.1", "react-dom": "16.13.1", ...

sequentially animating elements using animate css in a choreographed manner

I have created a unique jsfiddle with 20 boxes that I am trying to animate using the Animate.css plugin. The plugin can be found at daneden.me/animate. My goal is to animate each box one after the other in a sequential manner, but I seem to be having trou ...

Pass the most recent properties to the mousemove event handler

I am currently developing a click-and-drag feature, which involves: setting up a moveListener on the onMouseDown event having the moveListener trigger an action that updates certain props of the component (props.whichChange) cleaning up the mouseUp event ...

issue with brightcove player's complete event not triggering upon video replay

I have a videoplayer with an event listener added in an onTemplateReady function. Upon completion of the video, I want to replay it: videoPlayer.addEventListener(brightcove.api.events.MediaEvent.COMPLETE, completedCallback); function completedCallback(){ ...

`Troubleshooting a rotation problem with PhysiJS`

I've recently started working with this library and I've run into a persistent issue that has been quite challenging for me. My current setup involves two cubes, one utilizing physi.js and the other using three.js. I have a function in place to ...

Exploring the world of unit testing with Jest in Strapi version 4

In my quest to conduct unit tests using Jest for the recently released version 4 of Strapi, I have encountered some challenges. The previous guide for unit testing no longer functions as expected following the latest documentation updates. Despite my effor ...

Combining arrays in Javascript that share the same key by utilizing a loop

Can you advise on the most effective method to restructure an array for desired output? My goal is to combine all key values, whether in arrays or not, into objects with the same name key. Here is my current array: brands: [ 0:ZARA: {product: "ZARA Blac ...

How can I switch to another screen from the menu located within my Parent Component?

I've been working on adding a customized navigation menu to my react-native app, but I'm currently facing the challenge of not being able to navigate to the corresponding screens of the selected menu items. I tried using this.props.navigation.nav ...

Using VueJs and Laravel 5 for On input implementation

After following the steps outlined in the mentioned tutorial, I was able to achieve a perfect validation setup. However, my goal now is to implement real-time form validation without relying on a traditional submit button. I want the validation to occur as ...

Deactivate toggle effect by clicking on a different link

My existing JavaScript code changes the background color of a link when it is clicked: $(".button").click(function(){ $(this).css('background-color', '#555'); }); While this functionality works, I am looking to have the color tog ...