Reputation: 485
I am creating an express server/React app that has the option to set a global password. If the global password is set I don't want an unauthenticated user to be able to access anything on the server, including static files. I am using JWT for authentication.
To protect routes in React I use a class named AuthService
to get and post, which allows me to send a Bearer token with all of my requests. However, I cannot send a Bearer token with any of my static files because they are loaded through the src
tag of components. I am unsure how or if it is possible to send a Bearer token with them. Because of this even if a user is authenticated they still cannot access any static files.
How can I allow authenticated users to access static files?
Express Backend:
// index.js
import express from 'express';
import globalMiddleware from 'global.middleware.js';
const app = express();
app.all('*', globalMiddleware);
app.use('/api/auth', ...);
app.use('/api/users', ...);
...
app.use('/static', express.static(process.env.STATIC_FOLDER));
// global.middleware.js
import jwt from 'jsonwebtoken';
export default async (req, res, next) => {
if (req.path == '/api/auth/global/' || process.env.GLOBAL_PASSWORD === '') return next();
const authHeader = req.headers['authorization'];
const token = !!authHeader && authHeader.split(' ')[1];
if (!token) return res.sendStatus(401);
let decoded;
try {
decoded = await jwt.verify(token, process.env.JWT_TOKEN_SECRET);
} catch (err) {
return res.sendStatus(401);
}
if (!decoded.hasOwnProperty('globalPassword')
|| decoded.globalPassword !== process.env.GLOBAL_PASSWORD
) return res.sendStatus(401);
next();
}
React Frontend:
// auth.service.js
class AuthService {
get(page) {
return axios.get(API_URL + page, this.getTokenHeader());
}
getTokenHeader() {
const token = localStorage.getItem('token');
if (token) {
return {
headers: {
Authorization: 'Bearer ' + token
}
}
} else {
return {}
}
}
}
Upvotes: 1
Views: 1052
Reputation: 627
A possible alternative would be to return the jwt token in a cookie ideally HttpOnly (not readable from js thus preventing XSS attacks on it), Secure (only sent with https requests) and with SameSite=Strict attribute (to prevent CSRF).
After the login, all your subsequent https requests (static files included) from the same site will be embedded with that cookie. You would need to update the middleware to check the cookie rather than the headers. And you wouldn't need the AuthService anymore.
Upvotes: 1