Store JWT as a cookie in Vue JavaScript and ensure it is successfully saved before proceeding

Upon logging in, my page sends the login and password information to the backend, receives a jwt token in return, saves it to the cookies, and redirects to /home.

However, there seems to be an issue with the authentication check on the /home route. When checking immediately after login, the token is undefined and no redirect occurs

Here is the router configuration:

const routes = [
  {
    path: '/login',
    component: Login,
    beforeEnter: (to, from, next ) => {
      if(isAuthenticated()) next("/home");
      else next()
    }
  },
  {
    path: '/',
    redirect: '/login'
  },
  {
    path: '/home',
    component: Menu
  }

];
router.beforeEach((to, from, next) => {
  if(!isAuthenticated() && to.path !== '/login') next('/login');
  else next();
});

This is the authentication check middleware function:

export const isAuthenticated = () => {
    const token = getCookie("token");
    console.log(token)
    if (token) {
        const jwt = parseJwt(token)
        if (Date.now() >= jwt.exp * 1000) {
            console.log('unauthenticated - expired token')
            return false
        } else {
            console.log('authenticated - valid token')
            return true
        }
    } else {
        console.log('unauthenticated - no token in cookie')
        return false
    }
}

const getCookie = (name) => {
    const value = `; ${document.cookie}`;
    const parts = value.split(`; ${name}=`);
    if (parts.length === 2) return parts.pop().split(';').shift();
}


const parseJwt = (token) => {
    var base64Url = token.split('.')[1];
    var base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
    var jsonPayload = decodeURIComponent(atob(base64).split('').map(function(c) {
        return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
    }).join(''));

    return JSON.parse(jsonPayload);
}

The following is the store action for logging in:

login({ commit }, loginRequest) {
    commit("LOGIN_PENDING")

    axios.post("/api/login", loginRequest)
    .then(
      (response) => {
        document.cookie =`token=${response.data.token}`;
        commit("SET_TOKEN", response.data.token);
        commit("LOGIN_COMPLETE");
      },
      (error) => {
        if(error.response.status==401) {
          commit("SET_INVALID_LOGIN_CREDENTIALS", true);
          commit("LOGIN_COMPLETE");
        }   
      }
    )
  }

How can I ensure that the token is saved to the cookie (

document.cookie =<code>token=${response.data.token}
;)

I would greatly appreciate any assistance!

Answer №1

If you simply want to save the authentication status, consider implementing cookie-session on the backend. This package will manage everything for you automatically - check it out here: https://www.npmjs.com/package/cookie-session

Answer №2

After some investigation, I found the root cause of the issue - the login action in Vuex was missing an asynchronous declaration. By adding async to the login function and await to the axios post request, I was able to successfully resolve the problem.

async login({ commit }, loginRequest) {
    commit("LOGIN_PENDING")

    await axios.post("/api/login", loginRequest)
    .then(
        (response) => {
            document.cookie =`token=${response.data.token}`;
            commit("SET_TOKEN", response.data.token);
            commit("LOGIN_COMPLETE");
        },
        (error) => {
            if(error.response.status==401) {
                commit("SET_INVALID_LOGIN_CREDENTIALS", true);
                commit("LOGIN_COMPLETE");
            }   
        }
    )
}

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

Ways to effectively pair a radio button with a dropdown menu

function radioCheck() { document.getElementById("last").checked = "checked"; } <label> <input type="radio" name="Ppub" value="" checked="checked">All Dates </label> <br> <label> <input type="radio" id="last" name="Ppu ...

Adding custom data attributes to HTML tags in Vue.js

I have a question regarding adding a data attribute to the <html> element in vue.js (v2). I haven't been able to find any guidance on how to do this in the auto generated code or the documentation. The end goal is to achieve this desired output ...

What is the purpose of passing functions down to components in React?

It's interesting to think about why we choose to define all component functions in one central location, such as index.js, and then pass them down. Is there a good reason for this approach? For instance, if I need to create a click handler for a list ...

Alert: Ajax encountered an issue with the auto-refreshing field

When running a script I created for a self-updating field, I encountered the following error message: UpdateField.html:37 Uncaught ReferenceError: fieldname is not defined at HTMLInputElement.onchange (UpdateField.html:37) Script: <!DOCTYPE ht ...

Apply an opacity setting of 0.5 to the specific segment representing 30% of the scrollable div

I have a scrollable container for displaying messages. I would like to apply an opacity of 0.5 to the content in the top 30% of the container, as shown in this image: https://i.stack.imgur.com/NHlBN.png. However, when I tried using a background div with a ...

The local server for handling HTTP requests has ceased to operate

Recently, I set up the NPM package along with the http server within the "server" directory. Initially, everything was functioning smoothly; however, the server abruptly ceased operating. Upon attempting to launch the local http server, an error message a ...

Removing a child component in Vue

I've written this code snippet: Vue.component('parent', { template: ` <div> <child v-for='(child, index) in children' :key='index' :childNumber="index+1" v-on:removeChild="removeChild" /> < ...

Updating the value of a rails parameter with JavaScript

I am trying to enhance my search form by pre-populating the fields with the "last searched values" when a user submits a search. The search form and results are displayed on the same page, and if there is no previous search, the fields should show placehol ...

In reference to carrying out functions post partial page reload

For the web page I'm working on, I have set it up so that upon reloading, an ajax call is made to the server to retrieve and display data. Within my code, I have included: $(document).ready( function(){.... some work.... }); Now, I also have a refre ...

Getting the value from a .sh (Shell Script) file in React: How to do it?

There is a .sh file that contains the following code: echo "Hello" This code produces the output: Hello The question at hand is: I am trying to extract the output from the .sh file and integrate it into my React application. After exploring various ...

Attention all controllers summoned from one AngularJS document

Having recently delved into the world of AngularJS and Ionic, I've exhaustively searched for solutions both on this forum and beyond. Despite my efforts, nothing seems to be working. My goal is to create an application with a homepage featuring a ser ...

Integrating social login using vue-authenticate with passport in a Node.js environment

I've been working on integrating Facebook login with vue-authenticate and passport. Successfully logged into my Facebook account, I obtained the 'Callback code' as well. Here is my callback URL: http://localhost:8080/auth/callback?code=AQD0 ...

Extracting information from JSON using arrays

I'm facing a bit of a challenge with this one. I've been trying to use jQuery on my website to update an element. It works perfectly fine without using an array of data in JSON, but as soon as I introduce an array of data, it stops functioning. I ...

What is the process for completing a form and then going back to edit the data in PHP?

I am having trouble filling out a form and then being able to make changes to the entries later. However, every time I go back to modify the records, I want the form to still have the previous values intact. Unfortunately, when I tried putting " /> An ...

Issue with hook not updating when invoked inside useEffect

I'm encountering an issue with updating the state after fetching data from my API. The API response seems to be correct, but for some reason, my weatherData-hook is not getting updated and it returns undefined. Can anyone point out what mistake I migh ...

It is important for the button size to remain consistent, regardless of any increase in text content

My goal was to keep the button size fixed, even as the text on it grows. This is the current code I am using: .button { border: none; color: white; padding: 10px 50px; text-align: center; text-decoration: none; display: inline-block; font ...

Please request user input in order to generate a multiplication chart

Is there a way to ensure that the program works properly so that when the user inputs a value, it is included in the multiplication table? <html> <head> <title> Multiplication Table </title> <style> body{ font-family: aria ...

Steps to show the chosen index value in an alert pop-up using Ionic 2 framework

I'm in the process of trying to showcase a selected index value within an Ionic 2 alert box. However, I'm struggling to find the correct method to display it in the Ionic prompt. This pertains to the home.ts import { Component } from '@ang ...

Mysterious sayings encircling the words fetched through ajax

If the localhost is pointing to the folder named www, where the structure looks like: www/ file/test.cpp index.html I want to dynamically load the content of test.cpp into index.html and display it with the help of highlight.js. Below is the cod ...

Issue with rendering components list in React.js

I am currently working on a project using React, and I'm facing an issue where my list is not displaying on render(). In my parent component, I have a list of components coming from SearchResult. Below is the relevant portion of my code: class Create ...