Unauthorized: passport and jwt

Question:
How do i get the next function to run even if passport.authenticate returns false:

Basic Run Down of Code:
when you go to /secureroute on my website it uses the JWT stratagy to see if you authenticated. If you are it will console.log user info like name. But the problem starts when you arn’t authenticated. If you arn’t the function after passport.authenticate wont run thus theres just small text in white with a black background in the browser that reads: unauthorized

(I get this intire repl isn’t secure, im trying to do this all for a feture project that will use mongodb and cookies to store users and tokens)

app.get(
  "/secureroute",
  passport.authenticate("jwt", { session: false }),
  async (req, res) => {
    console.log("req.isAuthenticated: ", req.isAuthenticated());
    console.log("req.user: ", req.user);
    console.log("req.login: ", req.login);
    console.log("req.logout: ", req.logout);

    res.send(`welcome: ${req.user ? req.user.email : 'Guest'}`);
  }
);

Repl link:
https://replit.com/@OwenStritz/passsport-jwt?v=1

function getJwt() {
  console.log("in getJWT");
  return fakeLocal.Authorization?.substring(7);
};

passport.use(
  new JWTstrategy(
    {
      secretOrKey: "TOP_SECRET",
      jwtFromRequest: getJwt,
    },
    async (token, done) => {
      console.log("in jwt strat. token: ", token);

      if (token?.user?.email == "tokenerror") {
        let testError = new Error("somthing bad happend, pls try again");
        return done(testError, false);
      }
      if (token?.user?.email == "emptytoken") return done(null, false);

      return done(null, token.user)
    }
  )
);

No, this is secure; JWT is extremely secure if you effectively hide your keys

You can handle the authentication logic manually inside the route handler function.

1 Like

You can handle the authentication logic manually inside the route handler function.

how do i do that?

No, this is secure; JWT is extremely secure if you effectively hide your keys

i just wanted to point out that i was talking about how every thing was store, both the users and tokens were stored in a json file. (any body can look at it)

Use this as help: https://www.loginradius.com/blog/engineering/guest-post/nodejs-authentication-guide/.

A coding example of a login page.

const express = require('express');
const jwt = require('jsonwebtoken');

const app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

const secretKey = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwidXNlcm5hbWUiOiJqb2huZG9lIiwiaWF0IjoxNjg0NDg4NjYzfQ.v2MNdqsxtYjwHnrcwno3tTc-g64u1piVdEpCsRNNz4w';

// sample user data
const users = [
  { id: 1, username: 'johndoe', password: 'samplePassword' },
];

// HTML for login page with styles
app.get('/', (req, res) => {
  res.send(`
  <html>
    <head>
      <title>JWTLogin</title>
      <style>
        body {
          font-family: Arial, sans-serif;
          margin: 0;
          padding: 0;
          display: flex;
          align-items: center;
          justify-content: center;
          min-height: 100vh;
          background-color: #f5f5f5;
        }

        .login-container {
          width: 400px;
          padding: 20px;
          border-radius: 4px;
          background-color: #CF9FFF;
          box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
        }

        h1 {
          text-align: center;
        }

        label {
          display: block;
          margin-bottom: 8px;
        }

        input[type="text"],
        input[type="password"] {
          width: 100%;
          padding: 8px;
          border-radius: 4px;
          border: 1px solid #ccc;
        }

        button[type="submit"] {
          width: 100%;
          padding: 8px;
          margin-top: 16px;
          border: none;
          border-radius: 4px;
          background-color: #5D3FD3;
          color: #ffffff;
          font-weight: bold;
          cursor: pointer;
        }

        button[type="submit"]:hover {
          background-color: #ac7fdc;
        }
        :root {
          --drop-height: 200px;
          --logo-size: 48px;
          --offset: 50px;
          --shadow-height: 8px;
        }
        
        html, body {
          height: 100%;
          width: 100%;
          margin: 0;
        }
        
        .container {
          width: 100%;
          height: 100%;
          background-color: lightgray;
          position: relative;
        }
        
        .logo {
          width: var(--logo-size);
          height: var(--logo-size);
          border-radius: 100%;
          background-color: salmon;
          
          position: absolute;
          top: var(--offset);
          left: calc(50% - var(--logo-size)/2);
        }
      </style>
    </head>
    <body>
      <div class="login-container">
        <h1>Login Page</h1>
        <form method="POST" action="/login">
          <div>
            <label for="username">Username:</label>
            <input type="text" id="username" name="username" required>
          </div>
          <div>
            <label for="password">Password:</label>
            <input type="password" id="password" name="password" required>
          </div>
          <button type="submit">Login</button>
        </form>
      </div>
    </body>
  </html>
`);
});

// Login route
app.post('/login', (req, res) => {
  const { username, password } = req.body;

  // Find the user by username and password
  const user = users.find(u => u.username === username && u.password === password);

  if (user) {
    // Generate a JWT token
    const token = jwt.sign({ id: user.id, username: user.username }, secretKey);

    // Set the token in the Authorization header and redirect to the protected endpoint
    res.set('Authorization', `Bearer ${token}`);
    res.redirect(`/protected?token=${encodeURIComponent(token)}`);
  } else {
    res.status(401).json({ alert: 'Invalid credentials' });
  }
});

app.get('/protected', authenticateToken, (req, res) => {
  // Accessible only to authenticated users
  res.json({ message: 'Protected resource accessed' });
});

// Middleware to authenticate the token
function authenticateToken(req, res, next) {
  const authHeader = req.headers['authorization'];
  const token = req.query.token || (authHeader && authHeader.split(' ')[1]);

  if (token == null) {
    return res.sendStatus(401);
  }

  jwt.verify(token, secretKey, (err, user) => {
    if (err) {
      return res.sendStatus(403);
    }

    req.user = user;
    next();
  });
}

// Default route handler for undefined routes
app.use((req, res) => {
  res.status(404).json({ message: 'Not Found' });
});

// Start the server
app.listen(3000, () => {
  console.log('Server started on port 3000');
});

If you still don’t understand. Feel free to contact me. I have good knowledge on node js

1 Like