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!
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.