0
votes

I've been trying to build an backend application in nodejs in which I have two schemas: users and Profile. I'm trying to authenticate it using passport but seems like something is wrong with the code. When I executed it first time it worked but after that I made few changes and seems like I messed up and now I'm unable to find out what's wrong with my code. Now after I execute the login route in postman, I receive a token but when I use this token to get current user's profile based on the payload in token then even after adding the token in header(Authorization), I'm getting unauthorized. Here are the code files:

app.js

const express = require('express');
const bodyParser = require('body-parser');
const mongoose = require('./db/mongo');
const passport = require('passport')
const config = require('./config/config')
const setContentTypeJSON = require('./middleware/set-content-type-json');

const usersRouter = require('./routes/auth-routes');

const app = express();

app.use(setContentTypeJSON);
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

//Passport Middleware
app.use(passport.initialize())
require('./config/passport')(passport)


app.use(usersRouter);


const PORT = process.env.PORT || config.port;
mongoose.connect(config.mongoURL, { useNewUrlParser: true })
    .then(() => {
        console.log("Connection established!")
        app.listen(PORT);
    })
    .catch(() => {
        console.log("Connection failed!")
    })

passport.js

const JwtStrategy = require('passport-jwt').Strategy;
const ExtractJwt = require('passport-jwt').ExtractJwt;
const mongoose = require('mongoose');
const User = mongoose.model('users');
const keys = require('../config/config');

const opts = {};
opts.jwtFromRequest = ExtractJwt.fromAuthHeaderAsBearerToken();
opts.secretOrKey = keys.secretOrKey;

module.exports = passport => {
  passport.use(
    new JwtStrategy(opts, (jwt_payload, done) => {
      User.findById(jwt_payload.id)
        .then(user => {
          if (user) {
            return done(null, user);
          }
          return done(null, false);
        })
        .catch(err => console.log(err));
    })
  );
};

auth-routes.js

const express = require('express');
const router = express.Router();
const passport = require('passport')
const jwt = require('jsonwebtoken')
const authController = require('../controllers/auth')

router.post("/signup", authController.userSignup);
router.post('/login', authController.userLogin);
router.get('/current', authController.current);

module.exports = router;

auth.js

const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');
const passport = require('passport');
const config = require('../config/config');
const User = require('../models/user');

exports.userLogin = (req, res, next) => {
    const email = req.body.email;
    const password = req.body.password;

    User.findOne({ email })
        .then(user => {
            if (!user) {
                return res.status(404).json({
                    email: 'User not found'
                })
            }

            bcrypt.compare(password, user.password)
                .then(isMatch => {
                    if (isMatch) { //user login successful
                        const payload = {email: user.email, userId: user._id};
                        jwt.sign(payload,
                            config.secretOrKey,
                            {expiresIn: 3600},
                            (err,token)=>{
                                if(err){
                                    res.status(404).json({
                                        error: err
                                    })
                                }
                                res.json({
                                    success: true,
                                    email: payload.email,
                                    id: payload.userId,
                                    token: 'Bearer '+token,

                                })                               
                            })
                    } else {
                        return res.status(400).json({
                            password: 'Password Incorrect'
                        });
                    }
                })
        });
}

exports.current = passport.authenticate('jwt',
{session: false}),(req,res)=>{
    res.json(req.user)
}

In case you want to refer the two model files which I'm using to create Schemas are:

User.js

const mongoose = require('mongoose')
const uniqueValidator = require('mongoose-unique-validator')


const userSchema = mongoose.Schema({
  email: {type: String, required: true, unique: true},
  password: {type: String,required: true}  ,
  resetToken: String,
  resetTokenExpiration: Date
});

userSchema.plugin(uniqueValidator);

module.exports = mongoose.model("users",userSchema);

Profile.js

const mongoose = require('mongoose')
const Schema = mongoose.Schema;

const profileSchema = mongoose.Schema({
    user:{
        type: Schema.Types.ObjectId,
        ref: 'users'
    },
    fullname: {
        type: String,
        required: true
    },
    college:{
        type:String,
        required: true
    },
    department: {
        type: String,
        required: true
    },
    achievements:{
        type: [String],
    }
});

module.exports = mongoose.model("profile",profileSchema);

Any help will be thankful!

1

1 Answers

0
votes

There was a small error. Here in auth.js file, i replaced

exports.current = passport.authenticate('jwt',{session: false}),(req,res)=>{
...
}

with

exports.current = (req,res)=>{
...
}

And in auth-routes.js file, I edited

router.get('/current',passport.authenticate('jwt',{session: false}),authController.current);

This was the error maybe i need to revise my es6 basics again. It worked.