The passport JWT authorization failed, not a single message is being printed to the console

I am currently working on building a login and registration system. I have experience using passport before and had it functioning properly. However, it seems like the npm documentation has been updated since then. I am facing an issue where I cannot even console.log within the function I pass passport to. It has been quite challenging as I've been researching and troubleshooting this problem since last night.

At the moment, I am able to successfully register a user and authenticate them, which indicates that my register and authenticate routes are working fine. This has been verified through Postman. However, when I try to access the profile route, it returns unauthorized. Below, I will share what I am sending through Postman after describing the file structure and sharing the code from each file.

In the passport file, there is a console.log statement that doesn't seem to log anything, whereas the console.log in app.js is logging messages in the terminal. Here's what appears in my terminal:

Server started on port 3000 yay i am connected to databasemongodb://localhost:27017/authapp

If anyone could offer assistance, it would be greatly appreciated.

Here is the current file structure:

application
config
-database.js
-passport.js
models
-user.js
routes
-users.js
app.js
package.json

passport.js

   module.exports = function(passport){
    let opts = {}; 
    opts.jwtFromRequest = ExtractJwt.fromAuthHeaderWithScheme('jwt')  
    opts.secretOrKey = config.secret; 
    passport.use(new JwtStrategy(opts, (jwt_payload,done)=>{
        console.log(jwt_payload);  
        User.getUserById(jwt_payload._doc._id, (err, user)=>{  
            if(err){
                return done(err,false);
            }
            if(user){
                return done(null, user);
            }else{
                return done(null,false);
            }
        });
    }));
}

database.js

module.exports = {
    database:'mongodb://localhost:27017/authapp', 
    secret:'NintamaRantaro'
}

models/user.js

const mongoose = require('mongoose');
//bcrpypt for encrpyption
const bcrypt = require('bcryptjs');
//to connect to database 
const config = require('../config/database');


//Create the Schema
const UserSchema = mongoose.Schema({
    name: {
        type: String
    },
    email: {
        type: String,
        require: true,

    },
    username: {
        type: String,
        require: true
    },
    password: {
        type: String,
        require: true
    }
});

const User = module.exports = mongoose.model('User', UserSchema);


module.exports.getUserById = function(id, callback){
    User.findById(id, callback);
    console.log("got user by id")
}

module.exports.getUserByUsername = function(username, callback){
    const query = {username:username} 
    User.findOne(query, callback); 
}



module.exports.addUser = function(newUser, callback){ /
  bcrypt.genSalt(10, (err, salt) => {
    bcrypt.hash(newUser.password, salt, (err, hash) => {
      if(err) throw err;
      newUser.password = hash;
      newUser.save(callback);
      console.log("new user has been added")
    });
  });
}

module.exports.comparePassword = function(candidatePassword, hash, callback){
    bcrypt.compare(candidatePassword, hash, function(err, isMatch){
        if(err) throw err;
        callback(null, isMatch);
        console.log("compare pass complete")
    });
}

routes/users.js

const express = require('express');
const router = express.Router();
const passport = require('passport');
const jwt = require('jsonwebtoken');
const config = require('../config/database')
//Now that I created the model I will bring it in here.
const User = require('../models/user');
const bodyParser = require('body-parser')

//Registration 
router.post('/register', (req,res,next) =>{
    //res.send('registration');
    let newUser = new User({
        name: req.body.name,
        email: req.body.email,
        username: req.body.username,
        password: req.body.password  //I will run this password through bcrypt.hash which will has before db.
    });
    console.log("new instance of the User class has been created")
    User.addUser(newUser, function(err, user){ //I will create this addUser function inside the models user.js
        if(err){
            console.log(err);
            res.json({success:false, msg:'Registration Failed!'})
        }else{
            res.json({success:true, msg:'User is Registered!'})
        }
    });
});
//This will be my authentication route
router.post('/authenticate', (req,res,next)=>{
    const username = req.body.username;
    const password = req.body.password;

    User.getUserByUsername(username, (err, user)=>{
        if(err) throw err;
        if(!user){
            return res.json({success: false, msg:'user not found'})
        }
        User.comparePassword(password, user.password, (err, isMatch)=>{
            if(err) throw err;
            if(isMatch){
                const token = jwt.sign(user.toJSON(), config.secret, {
                    expiresIn:600000
                });
                res.json({
                    sucess:true,
                    token:'JWT ' + token,
                    user:{
                        id: user._id,
                        name: user.name,
                        username: user.username,
                        email: user.email
                    }
                });
            }else{
                return res.json({success:false, msg:'wrong pass'});
            }
        });
     });
});
// It failed at the line.
// const token = jwt.sign(user, config.secret, {
// Which I assume is mongoosejs object, which contains many methods and is not "serializable". 

router.get('/profile', passport.authenticate('jwt', {session:false}), (req, res, next) => {
  console.log(req.user)
  res.json({user: req.user});

});



module.exports = router;

app.js

const express = require('express');
//path is part of the cores module
const path = require('path');
const bodyParser = require('body-parser');
const cors = require('cors');
const passport = require('passport');
const mongoose = require('mongoose');
//database is in database.js this connects to  database:'mongodb://localhost:27817/authapp'
const config = require('./config/database')

mongoose.connect(config.database);

mongoose.connect(config.database);  

mongoose.connection.on('connected',function(){console.log('yay i am connected to database'+config.database)});


mongoose.connection.on('error',function(error){console.log('You have an error'+error)});


const app = express();


const users = require('./routes/users');

const port = 3000;

app.use(cors());



app.use(express.static(path.join(__dirname, 'public')))


app.get('/', function(req,res){res.send('Sending Response')})


app.use(bodyParser.json());


app.use(passport.initialize());
app.use(passport.session());

require('./config/passport')(passport);

app.use('/users', users)


app.listen(port, function(){console.log('Server started on port '+port)})

Postman after http://localhost:3000/users/register method:Post Body:

{
    "name":"hello",
    "email":"<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="4e262b2222210e39213c222a602d2123">[email protected]</a>",
    "username":"helloworld",
    "password":"123456"
}

200 OK { "success": true, "msg": "User is Registered!" }

After http://localhost:3000/users/authenticate method:Post body:

{
    "username":"helloworld",
    "password":"123456"
}

200 OK

{
    "sucess": true,
    "token": "JWTeyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI1YTk2YzA1ZmZjNDQ5YjBkZTI0ZTA3YTIiLCJuYW1lIjoiaGVsbG8iLCJlbWFpbCI6ImhlbGxvQHdvcmxkLmNvbSIsInVzZXJuYW1lIjoiaGVsbG93b3JsZCIsInBhc3N3b3JkIjoiJDJhJDEwJGl1eFE2V1IvaXJqRkxTZVV4MkhSVE80SlhzeEhrUklzbEhGeTVGL1ZQbGdSMVBEU2wwUkRlIiwiX192IjowLCJpYXQiOjE1MTk4MjkxMTksImV4cCI6MTUyMDQyOTExOX0.05uAxA9sQMzVHjc2kXoR86fpDzu1TQmsyFbGN_AcFRo",
    "user": {
        "id": "5a96c05ffc449b0de24e07a2",
        "name": "hello",
        "username": "helloworld",
        "email": "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="ef878a838380af98809d838bc18c8082">[email protected]</a>"
    }
}

After http://localhost:3000/users/profile

Headers:

Key: Authorization,
Value: JWTeyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI1YTk2YzA1ZmZjNDQ5YjBkZTI0ZTA3YTIiLCJuYW1lIjoiaGVsbG8iLCJlbWFpbCI6ImhlbGxvQHdvcmxkLmNvbSIsInVzZXJuYW1lIjoiaGVsbG93b3JsZCIsInBhc3N3b3JkIjoiJDJhJDEwJGl1eFE2V1IvaXJqRkxTZVV4MkhSVE80SlhzeEhrUklzbEhGeTVGL1ZQbGdSMVBEU2wwUkRlIiwiX192IjowLCJpYXQiOjE1MTk4MjkxMTksImV4cCI6MTUyMDQyOTExOX0.05uAxA9sQMzVHjc2kXoR86fpDzu1TQmsyFbGN_AcFRo

Unauthorized 401 Unauthorized

Answer №1

After encountering a frustrating issue, I managed to resolve it by taking the following steps: restarting my computer and servers, and then making a crucial change from user.toJSON() to {data:user}. This alteration allowed me to finally see the payload being printed to the console, revealing that it was coming in through an object named data. As a result, I adjusted my code to access jwt_payload.data._id instead of what I had initially. It seems that the npm documentation may have been updated, as I previously used jwt_payload._doc._id in another Mean app with passport integration. Interestingly, I recall not needing to include {data:user} before obtaining just user. Despite this unexpected behavior, registration and authentication processes worked fine with user.toJSON(), but the issue surfaced when navigating to the profile page. Moments of frustration made me consider giving up, but persistence paid off as I kept trying until success was achieved.

Answer №2

All files are in good shape. I encountered the same problem and here is the solution that worked for me:

    const JwtStrategy = require('passport-jwt').Strategy;
    const ExtractJwt = require('passport-jwt').ExtractJwt;
    const User = require('../models/user');
    const config = require('../config/database');

    module.exports = function(passport){
        let options = {};
        options.jwtFromRequest = ExtractJwt.fromAuthHeaderWithScheme('jwt');
        options.secretOrKey = config.secret;
        passport.use(new JwtStrategy(options, (jwt_payload, done) => {
            User.getUserById(jwt_payload._id, (err, user) => {
                if(err){
                    return done(err, false);
                }
                if(user){
                    return done(null, user);
                }else{
                    return done(null, false);
                }
            });
        })
         );
      }

Please refer to the documentation of passport-jwt-npm for more details.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Template for Vue.js Component Registration

Below is a simple Vue component example: const MyComponent = Vue.component('my-component', { data () { // data here... }, methods: { // methods here... }, template: '<p>Hello, world !!!</p>' }); I ...

How can I use JavaScript to create a drop-down menu that only appears after selecting the previous one?

<div class="row"> <div class="col-md-4"> <label for="selectCustomers">Customer Select</label> <select class="form-control pointer" name="tableCustomers" id=" ...

Angular/JS - setTimeout function is triggered only upon the occurrence of a mouse click

I'm currently working on a website that calculates the shortest path between two points in a grid utilizing AngularJS. Although I have already implemented the algorithm and can display the colored path, I am facing an issue where the color changes ti ...

Can you explain the purpose of the statement `var MyConstructor = function MyConstructor()`?

Can you explain the distinction between these two code snippets: var NodestrapGenerator = module.exports = function NodestrapGenerator() { yeoman.generators.Base.apply(this, arguments); // more code here }; and: var NodestrapGenerator = module.expor ...

Ways to update the DOM once a function has been executed in VUE 3 JS

I'm working on implementing a "like" or "add to favorite" feature in VUE 3. However, I'm facing an issue where the UI doesn't update when I like or unlike something. It only refreshes properly. I'm using backend functions for liking and ...

Need help with resetting a value in an array when a button is clicked?

Using Tabulator to create a table, where clicking on a cell pushes the cell values to an array with initial value of '0'. The goal is to add a reset button that sets the values back to '0' when clicked. component.ts names = [{name: f ...

Unable to create account using PHP

Every time I attempt to create an account, the data I receive is always problematic. The username must be between 3 and 15 characters I find it frustrating that the account creation never goes through successfully. What baffles me even more is that af ...

Utilizing a range input (slider) to extract data of importance

When dynamically adding a slider to a page using a specific string, like the one shown below: "<input type=\"range\" name=\"aName\" min=\"1\" max=\"9\"/>"; After appending it to the page with pure JavaScript, ...

What steps can be taken to address the error message "FATAL: Unable to load template" encountered while using

I'm encountering the issues documented here and here on GitHub. I'm working on incorporating documentation for my Next.js code, and below is my jsdoc configuration file. { "tags": { "allowUnknownTags": true, "di ...

Fill out FormBuilder using data from a service within Angular2

I am working with an Angular2 model that I'm filling with data from a service. My goal is to use this model to update a form (created using FormBuilder) so that users can easily edit the information. Although my current approach works, I encounter er ...

What is the best way to initialize React-map-gl with the user's current location as the default latitude and longitude?

Is there a way to render the map with default values of viewport set to user's location without needing to click a locate me button? <ReactMapGL mapboxApiAccessToken={mapboxApiKey} mapStyle="mapbox://styles/mapbox/streets-v11" ...

What is the best way to effectively integrate jQuery plugins into Node.JS?

Getting Started with Node.JS I recently ventured into the world of Node.JS, leveraging my existing expertise in JavaScript and jQuery. While I successfully installed jQuery using npm install jquery, incorporating plugins into my code has proven to be a bi ...

The significance of API Input Validation and Steering Clear of Lengthy Conditional Statements

Currently, I am working on ensuring that my API functions correctly even in cases of bad or missing data. At the moment, I have an if statement that checks for any missing inputs. If an input is missing, it returns false, otherwise there is a large else b ...

Using jQuery to create clickable URLs within a rollover div

I am looking to have the div appear on a mouse over effect in the following code. Is there a way for me to input a url based on the data that is passed to it? Anchorage: ["Anchorage", "(555)555-5555"], (This represents the data being posted) AtlanticCit ...

Create a dynamic and interactive website using a combination of jQuery and AngularJS

I recently came across an interesting tidbit on the FAQs of Angular stating that "Angular can use jQuery if it's present in your app when the application is being bootstrapped". This got me thinking, is it considered a best practice to include both j ...

Change the size of the font with a slider in VueJS

I have been utilizing the project found at This particular project allows end-users to reuse Vue components as editable sections by providing a styler overlay for adjusting content within a div or section. After installation, I added a slider which now ap ...

Troubleshooting: Why are my images not displaying in webpack and node.js setup?

My problem: I'm facing an issue with background images in my project. I have included two images and used file-loader to bundle them through webpack. While the images display correctly in the app during development using webpack-dev-server, they disap ...

Make sure to give an item a little extra attention by highlighting or making it blink after it has

I have a collection of items that I utilize to construct an unordered list using ng-repeat. When a new item is added, I want it to stand out by blinking or having some kind of effect to grab the user's attention. While it would be easy with jQuery, I ...

Displaying a division when a button is pressed

Despite my best efforts, I can't seem to get the chosen div to show and hide when the button is pressed. <button id="showButton" type="button">Show More</button> <div id="container"> <div id="fourthArticle"> <i ...

Ensuring the safety of ajax GET/POST communication between client and server

Let's say I'm working with a specific API and my file server.php is responsible for connecting to the API service. On the client side, I am using an AJAX call like this: $http({ url : 'server/server.php', method : &ap ...