'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:-
Below is the error I see in the browser console:-
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 |


