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

Steps to activate a single button within a deactivated fieldset

Is there a way to deactivate all elements within a Fieldset, while keeping certain buttons active? Check out this demo. <fieldset ng-disabled="true"> <legend>Personalia:</legend> Name: <input type="text"><br> Em ...

Getting the Request Body Content in Express Middleware

Currently, I am in the process of developing a small API logger to use as an Express middleware. This logger is designed to gather data from both the request and response objects, then store this information in a JSON file on disk for later reference. Her ...

Ways to transform an Array into an object

I had the idea to create a personalized dictionary for customers by utilizing the reduce function. Currently, I am achieving this using the forEach method. const customers = [ { name: 'ZOHAIB', phoneNumber: '0300xxxxx', other: ' ...

Is it possible for Response.Redirect and OnBeforeUnload to cooperate effectively?

Is there a way to detect if the server-side code has sent a Response.Redirect in an OnBeforeUnload event? I need to alert the user before they navigate away from a page, but I don't want the prompt to appear when the server redirects. I'm dealin ...

Having trouble with playing audio from an array in Javascript

I've been working on creating a Drum Kit website. My approach involves using an array to hold all the sound files, and using a loop to call the play() function. However, I encountered an issue when trying to load the sounds - the debug console showed: ...

Amazon S3 Landing Page Featuring Contact Form

Although S3 is not a fileserver, it serves as an excellent tool for managing static websites. The majority of my projects are 99% static, making it ideal for this particular project. As an AWS Solutions Architect, I am struggling to find the most straightf ...

Utilizing variable index to access nested objects

When my Ajax request returns a response, the data takes the form of an object shown below: How can I access the value? Keep in mind that idVariable is a variable. data.test1.idVariable.test2.value The result of the code above is: undefined. ...

How can we eliminate all elements from jQuery except for the first and second elements?

HTML <div class="geo_select"> <h3>header 3</h3> in Above HTML code i want to remove all element except <h3> and default content<div> inside the <div class='geo_select'> in jquery.. How to remove all ...

Creating a div overlay triggered by the addition of a child tag

Using the Paypal zoid feature, I have a button that opens an iframe in the parent div when clicked. However, the iframe causes the other contents of the website to shift around, making it look messy. I'm wondering if there is a way to make the parent ...

Is it possible to display different alert messages based on the language chosen?

Recently, I implemented a newsletter pop-up feature that allows users to sign up for a weekly newsletter. When a user tries to submit without entering their email address, an alert message pops up prompting them to do so. This is beneficial but now I wan ...

How can I incorporate percentage values into input text in Angular?

How can I include a percent sign in an input field using Angular, without relying on jQuery? I am looking for a solution that is identical to what I would achieve with jQuery. Here is the current status of my project: ...

"Unlocking the JSON element with jQuery Ajax: A step-by-step guide

I am trying to pinpoint a specific element within my JSON data: { "taskMeta": "Some meta info", "tasksLib": [ { "task001": { "id":"1", "createDate":"01.02.17", "dueDate":"02.03.17", "au ...

Challenges with Vue 2 Cli CSP Build - Overcoming the Eval and new Function Obstacle

Recently, I had to update a static Vue application to comply with CSP requirements within the Vue 2 CLI environment. Despite researching extensively online, it became clear that in order for Vue to be CSP compliant, render functions and a runtime version ...

Error: Unable to retrieve the specified ID

One unique aspect of my backbonejs app is the model structure: var Store = Backbone.Model.extend({ urlRoot: "/stores/" + this.id }); This is complemented by a router setup like so: var StoreRouter = Backbone.Router.extend({ routes: { 's ...

The issue with Vuex and Typescript is that when using mutation object payloads, they are consistently undefined

Every time I run my code, the object payload I'm passing as a secondary parameter to my Vuex mutation method ends up being undefined. Both my Vuex and component files are coded in TypeScript. When looking at my index.ts file for my Vuex store (where ...

What is the best way to extract the src attribute from an image tag nested within innerHtml?

In the developer tools, navigate to console and enter: var x= document.getElementsByClassName('ad-area')[0].innerHTML; x returns: '<a href="/members/spotlight/311"><img class="block-banner" src="https://tes ...

What is the proper way to define the scope for invoking the Google People API using JavaScript?

I am attempting to display a list of directory people from my Google account. export class People { private auth: Auth.OAuth2Client; private initialized: boolean = false; private accessToken: string; constructor(private readonly clientEmail: strin ...

Get the Google review widget for your web application and easily write reviews using the Google Place API

I developed a platform where my clients can provide feedback and ratings on my services through various social media platforms. Currently, my main focus is on collecting Google reviews using a Google widget/flow. The image above displays the list of avai ...

The random number generator in TypeScript not functioning as expected

I have a simple question that I can't seem to find the answer to because I struggle with math. I have a formula for generating a random number. numRandomed: any; constructor(public navCtrl: NavController, public navParams: NavParams) { } p ...

Using jquery to dynamically change audio source on click

Is there a way to dynamically change the audio src using jquery? <audio id="audio" controls="" > <source src="" type="audio/mpeg" /> </audio> <ul id="playlist"> <?php if($lists) { foreach ($lists as $list) { ?> ...