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

Steps to combine multiple arrays into a unified array:1. Begin by allocating a

To form a league table, I have multiple individual arrays filled with data. In order to sort them by points, I want to merge these arrays into a single array called "teams". However, I am unsure if there is a function available to achieve this specific f ...

Unable to make a POST request to the GitHub v3 API

I'm attempting to generate a public gist using JavaScript without any authentication - all purely client-side. var gist = { "description": "test", "public": true, "files": { "test.txt": { "content": "contents" ...

Closing WebSocket connection after sending data

I came across an interesting blog post titled Experimenting with Node.js and decided to try setting it up on my own using the author's provided gist. Unfortunately, I encountered some issues. After further investigation, I discovered that even though ...

How to extract user data from a JWT token using Node.js?

In my MEAN stack authentication application, I am utilizing Node and Angular. After a successful login, I set a JWT token and store it in a session within the controller by assigning the token to config.headers through a service interceptor: var token = j ...

Maximizing Efficiency: Utilizing a Single jQuery Function to Retrieve Specific Values

I have a webpage with select menus for choosing user type, minimum age, and maximum age. I want to select options and send values as an object array to ajax. Initially, the getAjax function is working when the page loads. However, it stops working when I c ...

How to Perform a Method Call or Array Iteration in JSX within HTML

Encountering a new issue that I haven't faced before, this is my first time working on something like this and finding a solution is proving to be tricky. Currently, I'm using SendGrid to send an HTML email through a POST request in express on N ...

Updating an Angular directive with dynamically added ng-module and ng-change attributes

Can someone check if I'm on the right track? Preamble: I've created a Typeahead class that fetches data and keeps it within itself. The class has the following structure: input: stores the search text. list: stores the results. change: a funct ...

Troubleshooting the issue of AngularJs location.path not successfully transferring parameters

My page has a Login section. Login.html <ion-view view-title="Login" name="login-view"> <ion-content class="padding"> <div class="list list-inset"> <label class="item item-input"> <input type="te ...

What is the proper way to display the date and time 2021-11-14T18:30:00.000+00:00?

Here is my ts file code: mydate: Date = new Date('2021-11-14T18:30:00.000+00:00'); However, I want the date to be in this format:- 07-July-2022 If anyone can assist with achieving this format, it would be greatly appreciated. Thank you! ...

A guide to querying JSON data in a backend database with JavaScript

My backend JSON DB is hosted on http://localhost:3000/user and contains the following data: db.json { "user": [ { "id": 1, "name": "Stephen", "profile": "[Unsplash URL Placehol ...

Looping the jQuery Ajax success function

Utilizing Ajax to input an array of data into a database. At the moment, when clicking on "#bookingbutton," it triggers a return block of HTML containing the ".select-room-button" button. I have incorporated the code for ".select-room-button" within the ...

I'm encountering an issue with VUEJS components including my show route in their get call. How can I make my journals/:id pages function properly without encountering a Mime

I encountered a MIME type error stating: Refused to apply style from 'http://localhost:8080/journals/assets/css/main.css' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled. ...

Click to move directly to a specific section

This question may be common, but despite my research efforts, I have been unable to find a solution. I want to issue a disclaimer that I am new to javascript and jQuery. Here is an overview of what I am trying to achieve: I want two images that, when cli ...

Issue with Next JS router.push not functioning unless the page is refreshed

I'm currently running Next.js 14.2 in my project with the page directory structure. After building and starting the application using npm start, a landing page is displayed with a login button that utilizes the <Link> component. I have also disa ...

Do you only need to utilize Provider once?

When using the redux module in react-native, it is common practice to utilize createStore from 'redux'. I am curious, is it sufficient to use <Provider/> just once to make the Redux store accessible throughout our app? import ReactDOM from ...

In what situations is it appropriate to utilize the getInnerHtml() method?

Within Protractor, an ElementFinder instance has access to the getInnerHtml() method: var elm = element(by.id("myid")); expect(elm.getInnerHtml()).toEqual("test"); Interestingly, this method is not included in the official API list. Can you think of any ...

Creating a case-insensitive path for pages in NextJS can be achieved by ensuring that all

I have a file named about.tsx under the pages folder. This means that the path for accessing the page is /about, allowing me to visit it through example.com/about. Strangely, attempting to access the same page via example.com/About results in a 404 error ...

The post page remains out of reach for Ajax

I've been struggling for hours to identify the issue with this code. I realized that I am unable to access the updateuser.php file even though it is in the same directory and the filenames are correct. Can someone please review the code below and let ...

Unable to view nodemon console updates and logs while utilizing lerna

https://i.stack.imgur.com/XxUza.png After launching the node express app and react app, there are no logs showing up. Any suggestions on how to address this issue? Appreciate any help, thank you. ...

tips for extracting data from a javascript chart without an internet connection

Recently, I've been exploring a website that contains a fascinating javascript chart displaying a simple time series. When hovering over the data points on the chart, a popup window reveals the exact value of each point. While I am aware of methods t ...