How to get logged in user? req.user is undefind

Viewed 406

How to get logged in user in express app. I want to know witch user create post. This is my Post.js model:

const postsSchema = mongoose.Schema(
  {
    user: {
      type: mongoose.Schema.Types.ObjectId,
      required: true,
      ref: 'User',
    },
    title: {
      type: String,
      required: true,
    },
    description: {
      type: String,
      required: true,
    },
    image: {
      type: String,
      required: true,
    },
    category: {
      type: String,
      required: true,
    },
    numLikes: {
      type: Number,
      required: true,
      default: 0,
    },
    comments: [commentSchema],
  },
  {
    timestamps: true,
  }
);

This is my authUser function where i log in user with email and password:

const authUser = async (req, res) => {
  const { email, password } = req.body;

  const user = await User.findOne({ email });

  if (user && (await user.matchPassword(password))) {
    res.json({
      _id: user._id,
      name: user.name,
      email: user.email,
      isAdmin: user.isAdmin,
      token: generateToken(user._id),
    });
  } else {
    res.status(401);
    throw new Error('Invalid email or password');
  }
};

generateToken function is JWT:

import jwt from 'jsonwebtoken';

const generateToken = id => {
  return jwt.sign({ id }, 'abc123', {
    expiresIn: '30d',
  });
};

export default generateToken;

When i create post i want to know user who created it, this is my create post function:

const createPost = async (req, res) => {
  const post = new Post({
    user: req.user._id,
    title: 'Sample Title',
    description: 'Sample Desc',
    image: '/images/sample.jpeg',
    category: 'Sample Category',
    numLikes: 0,
  });

  const createPost = await post.save();
  res.status(201).json(createPost);
};

When i try to create post i got this error in console:

UnhandledPromiseRejectionWarning: TypeError: Cannot read property '_id' of undefined.

I can log in with postman, i can register, i can get user by id. How to tell my app Hey i am logged in user and have access to req.user object

3 Answers

You need to have the client send the token back to you, which you then validate (typically via a middleware affecting some section of endpoints so you don't have to call a validation function in individual endpoints).

If instead, express is also your front end, then you need to use a library like express-session https://www.npmjs.com/package/express-session to manage cookies. A good example is available on their page:

// Use the session middleware
app.use(session({ secret: 'keyboard cat', cookie: { maxAge: 60000 }}))

// Access the session as req.session
app.get('/', function(req, res, next) {
  if (req.session.views) {
    req.session.views++
    res.setHeader('Content-Type', 'text/html')
    res.write('<p>views: ' + req.session.views + '</p>')
    res.write('<p>expires in: ' + (req.session.cookie.maxAge / 1000) + 's</p>')
    res.end()
  } else {
    req.session.views = 1
    res.end('welcome to the session demo. refresh!')
  }
})

Otherwise you've sent the token to client and done nothing with it.

Do you need of a middleware like this:

module.exports = (req, res, next) => {
  // Authorization token example: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiaWQiOiIxIiwiaWF0IjoxNTE2MjM5MDIyfQ.dYo0kOIhum5mMTRV8CAn8gQ_6aqoDQLE--vCZD4E-fg
  const { authorization } = req.headers

  if (!authorization) return res.send({ message: 'Token not provided', code: 400 })

  const [ schema, token ] = authorization.split(' ')

  if (schema !== 'Bearer') return res.send({ message: 'Token is bad formated', code: 400 })

  if (!token) return res.send({ message: 'Invalid token', code: 400})

  jwt.verify(token, 'abc123', (error, decoded) => {
    if (error) return res.send({ message: error.message, code: 401})

    req.userId = decoded.id
  })

  next()
}

Hope this is helpful for you.

The first thing you should do is to send token back to the client or attach cookies to your response. After which you set up a middleware that will check cookies or token in your case using jwt.verify(token, jwtSecret). That will return the id and all other things you stored in the token, then you then store them in req.user, where you will be able to access the details later.

//if you stored token in cookies -
const {accessToken} = req.signedCookies
        const payload = isTokenValid(accessToken) //verify the token
        req.user = payload.user;
        return next();
//if you stored in auth header
const bearerToken = req.headers.authorization
//bearerToken = "Bearer token"
const token = bearerToken.split(" ").join(",")[1]
//verify the token using jwt
const payload = isTokenValid(token)
req.user = payload
return next()

Related