'NodeJS API App - Unable to display backend images in a browser - "The user is not authorized"

I have created a NodeJS backend api used to serve up a number of shop products. If I add the path of a saved imagine into the browser address bar (e.g. 'http://localhost:3000/public/upload/0C1D7F7C-42B1-4A62-B4C3-A042BEB6A6B5.jpg-1604606693142.jpeg') I can not view the saved image in the browser, I get the following error - "The user is not authorized".

The path to the backend image folder is this - public/uploads

The path to the folder should not require any authorization because I added an entry to the 'public/uploads' folder in my 'jwt.js'. See 'jwt.js' file below:-

const expressJwt = require('express-jwt');

function authJwt() {
    const secret = process.env.secret;
    const api = process.env.API_URL;
    return expressJwt({
        secret,
        algorithms: ['HS256'],
        isRevoked: isRevoked
    }).unless({
        path: [
            { url: /\/public\/uploads(.*)/, methods: ['GET', 'OPTIONS'] },
            { url: /\/api\/v1\/products(.*)/, methods: ['GET', 'OPTIONS'] },
            { url: /\/api\/v1\/categories(.*)/, methods: ['GET', 'OPTIONS'] },
            { url: /\/api\/v1\/orders(.*)/, methods: ['GET', 'OPTIONS', 'POST'] },
            `${api}/users/login`,
            `${api}/users/register`
            // { url: /(.*)/ },
        ]
    });
}

async function isRevoked(req, payload, done) {
    if (!payload.isAdmin) {
        done(null, true);
    }

    done();
}

module.exports = authJwt;

This is my 'app.js' file:-

const express = require('express');
const app = express();
const morgan = require('morgan');
const mongoose = require('mongoose');
const cors = require('cors');
require("dotenv/config");
const authJwt = require("./helpers/jwt");
const errorHandler = require("./helpers/error-handler");
const swaggerJsDoc = require('swagger-jsdoc');
const swaggerUi = require('swagger-ui-express');
const router = express.Router();


const options = {
    swaggerDefinition: {
        openapi: "3.0.0",
        info: {
            title: "Libray API",
            version: "1.0.0",
            description: "A simple Express Library API"
        },
        servers: [
            {
                url: "http://localhost:3000"
            }
        ],
    },
    apis: ["./routes/*.js"]
}

const specs = swaggerJsDoc(options);
app.use("/api-docs", swaggerUi.serve, swaggerUi.setup(specs));


// Cors
app.use(cors());
app.options('*', cors());


// Middleware - for dealing with JSON objects posted from the frontend
app.use(express.json());
app.use(morgan('tiny'));
app.use(authJwt());
app.use("/public/uploads", express.static(__dirname + "/public/uploads"));
app.use(errorHandler);


//Routes
const categoriesRoutes = require('./routes/categories');
const productsRoutes = require('./routes/products');
const usersRoutes = require('./routes/users');
const ordersRoutes = require('./routes/orders');

const api = process.env.API_URL;

app.use(`${api}/categories`, categoriesRoutes);
app.use(`${api}/products`, productsRoutes);
app.use(`${api}/users`, usersRoutes);
app.use(`${api}/orders`, ordersRoutes);


// Connection to MongoDB database
mongoose.connect(process.env.CONNECTION_STRING, {
    useNewUrlParser: true,
    useUnifiedTopology: true,
    dbName: 'eshop-database'
})
.then(() => {
    console.log('Database connection is ready');
})
.catch((err)=> {
    console.log(err);
})


app.listen(3000, () => {
    console.log('Server is running http://localhost:3000');
})

Below is a screen shot showing my NodeJS project structure:-

enter image description here

Below is the error I see in the browser console:-

enter image description here

Can anyone help please?



Solution 1:[1]

Try to add a path to the static files like that:

const path = require("path");

app.use("/public/uploads", express.static(path.join(__dirname, "../public/uploads")))

Solution 2:[2]

I think you should swap this 2 lines with each other:

app.use(authJwt());
app.use("/public/uploads", express.static(__dirname + "/public/uploads"));

To

app.use("/public/uploads", express.static(__dirname + "/public/uploads"));
app.use(authJwt());

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Eslam Gohar
Solution 2 lamtacvu