fetch request pending if I add this jwt verify function

Issue

I’m working on a login demo page. if I try to define the authenticate jwt token block into a function outside of app.get. When I fetch the data. It’s always pending.

app.get('/posts',app.get('/posts',authenticate_token,(req,res)=>{
    if (!authstring) {
        res.json({'status':'error','statusinfo':'please login'})
    }else{
        let autheduser = authenticate_token(req);
        console.log(autheduser);
        res.status(200).json(userinfo.find(user=>user.username === autheduser));
    }
});

The function I wrote to verify JWT token is like this.

function authenticate_token(req, res) {
  let authstring = req.headers.authorization;
  authstring = authstring.split(" ");
  authstring = authstring[1];
  console.log(authverified);
  return authverified;
}

But if I write like this. It works perfectly fine.

app.get("/posts", (req, res) => {
  let authstring = req.headers.authorization;
  authstring = authstring.split(" ");
  authstring = authstring[1];
  if (!authstring) {
    res.json({ status: "error", statusinfo: "please login" });
  } else {
    let authverified = JWT.verify(authstring, process.env.accTokenSecret);
    console.log(authverified);

    res
      .status(200)
      .json(userinfo.find((user) => user.username === authverified));
  }
});

What’s the reason that the second one works but first one don’t?

update:
I edited code follow Drashti Kheni’s suggestion.But the request is still in pending state.

function authenticate_token(req) {
   let authstring = req.headers.authorization;
   authstring = authstring.split(' ');
   authstring = authstring[1];
   let authverified=JWT.verify(authstring,process.env.accTokenSecret);
   console.log(authverified);
   return authverified;
};

The console.log in function authenticate_token works.But the console.log inside else block does not run.

Update 2: I put the authrization code out. And it seems the authenticate_token function can return value correctly outside of the request handler function. So,what is my problem here?

let austring = 'eyJhbGciOiJIUzI1NiJ9.dGFv.7BPuAYEbrNdOox_CTNK_-6dwzjzmHqY-5oSCdtYS5Kc'

function authenticate_token(req) {
    console.log(req);
    let authstring = austring;
    authstring = authstring.split(' ');
    authstring = authstring[1];
    //console.log(authstring);
    let authverified = JWT.verify(authstring, process.env.accTokenSecret);
    console.log(authverified);
    //console.log(authverified);
    return authverified;
};

console.log(austring);

Solution

Explain

Firstly, it’s good to extract the common code to a function. But you don’t use the function correctly. Look at this line:

app.get('/posts',authenticate_token,(req,res)=>{

You’re using authenticate_token as a middleware. Express.js use middleware to handle requests. At the end of a middleware, you can choose between:

  • Send a response to client

or

  • Pass the control to the next middleware using next()

Now look at the function authenticate_token

function authenticate_token(req, res) {
  let authstring = req.headers.authorization;
  authstring = authstring.split(" ");
  authstring = authstring[1];
  console.log(authverified);
  return authverified;
}

There is no response for the client and you don’t pass the control for the next middleware either. So, after calling this middleware, no one takes care of your request, and it is stuck.

Action

We can try this simple logic: in the middleware, we check if the Authorization header is present and is a valid token. If it isn’t the case, we respond to the client. Finally, if the token is valid we pass the control to the next middleware for further treatments.

function authenticate_token(req, res, next) {

  let authstring = req.headers.authorization;  
  // request doesn't contains Authorization header -> not valid
  if(!authstring) {
     return res.json({'status':'error','statusinfo':'please login'});
  }
 
  authstring = authstring.split(" ");  
  // The format of Authorization header is not correct -> not valid
  if(authstring.length < 2) {
    return res.json({'status':'error','statusinfo':'please login'});
  }

  authstring = authstring[1];
  let authverified = JWT.verify(authstring, process.env.accTokenSecret);  
  // the token is not verified
  if(!authverified) {
     return res.json({'status':'error','statusinfo':'please login'});
  }

  // happy case, the token is verified, we pass the control to the next middleware
  res.locals.authverified = authverified; // it will available in the next middleware
  next();
}

Then in your main middleware, you can retrieve authverified value from res.locals

app.get('/posts',authenticate_token,(req,res)=>{
    
        let autheduser = res.locals.authverified;
        console.log(autheduser);
        res.status(200).json(userinfo.find(user=>user.username === autheduser));
    }
});

You can read more about Express middleware from the official documentation

Answered By – Đăng Khoa Đinh

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published