2

Github : https://github.com/UJJWAL2001/Pro-Shop/tree/main/backend

I am trying to use JWT token for protecting my routes via a middleware given below

import jwt from 'jsonwebtoken'
import User from '../models/userModel.js'
import asyncHandler from 'express-async-handler'

const protect = asyncHandler(async (req, res, next) => {
  let token

  if (
    req.headers.authorization &&
    req.headers.authorization.startsWith('Bearer')
  ) {
    try {
      token = req.headers.authorization.split(' ')[1]

      const decoded = jwt.verify(token, process.env.JWT_SECRET)

      req.user = await User.findById(decoded.id).select('-password')
      console.log(req.user)
      next()
    } catch (error) {
      console.log(error)
      res.status(401)
      throw new Error('Not Authorized, token failed')
    }
  }

  if (!token) {
    res.status(401)
    throw new Error('Not authorized, no token found')
  }

  next()
})

export { protect }

I am hitting the correct route but still receiving this

{
    "message": "Not found - /api/users/profile",
    "stack": "Error: Not found - /api/users/profile\n    at notFound (file:///Users/ujjwalchaudhary/Desktop/proshop/backend/middleware/errorMiddleware.js:2:17)\n    at Layer.handle [as handle_request] (/Users/ujjwalchaudhary/Desktop/proshop/node_modules/express/lib/router/layer.js:95:5)\n    at trim_prefix (/Users/ujjwalchaudhary/Desktop/proshop/node_modules/express/lib/router/index.js:317:13)\n    at /Users/ujjwalchaudhary/Desktop/proshop/node_modules/express/lib/router/index.js:284:7\n    at Function.process_params (/Users/ujjwalchaudhary/Desktop/proshop/node_modules/express/lib/router/index.js:335:12)\n    at Immediate.next (/Users/ujjwalchaudhary/Desktop/proshop/node_modules/express/lib/router/index.js:275:10)\n    at Immediate._onImmediate (/Users/ujjwalchaudhary/Desktop/proshop/node_modules/express/lib/router/index.js:635:15)\n    at processImmediate (internal/timers.js:464:21)"
}

I checked that i am hitting api/users/profile -> protect -> getUserProfile->app.use(notFound)->app.use(errorHandler) But the cycle should by terminated at res.json({...}) of getUserProfile

You can check the routes and middlewares at my github repo mentioned above.

1 Answers1

0

It seems that when using asyncHandler(), when you call the next function, it keeps executing code so below each next(), my solution was to put return, for example, in your protect middleware after the next().

try {
    token = req.headers.authorization.split(' ')[1]
    const decoded = jwt.verify(token, process.env.JWT_SECRET)

    req.user = await User.findById(decoded.id).select('-password')
    console.log(req.user)
    next()
    return;    // here
} catch (error) {
    console.log(error)
    res.status(401)
    throw new Error('Not Authorized, token failed')
}

And do it in the controllers too, when you use res.json or res.send do it with a return like

return res.json({message: 'message'})

asyncHandler won't let you return res.json, so I think putting a return on the next line is one way to fix it.

Tyler2P
  • 2,324
  • 26
  • 22
  • 31
Pablo
  • 7
  • 1
  • 4