ExpressReactJWT:如何通过静态文件请求发送Bearer令牌



我正在创建一个express server/Rect应用程序,该应用程序可以选择设置全局密码。如果设置了全局密码,我不希望未经身份验证的用户能够访问服务器上的任何内容,包括静态文件。我正在使用JWT进行身份验证。

为了保护React中的路由,我使用了一个名为AuthService的类来获取和发布,这允许我在所有请求中发送一个Bearer令牌。但是,我不能将Bearer令牌与我的任何静态文件一起发送,因为它们是通过组件的src标签加载的。我不确定如何或是否有可能与他们一起发送Bearer代币。因此,即使用户通过了身份验证,他们仍然无法访问任何静态文件。

如何允许经过身份验证的用户访问静态文件?

快速后端:

// 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前端:

// 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 {}
}
}
}

一个可能的替代方案是在cookie中返回jwt令牌,理想情况下是HttpOnly(无法从js读取,从而防止XSS对其的攻击(、Secure(仅通过https请求发送(和SameSite=Strict属性(以防止CSRF(。

登录后,来自同一网站的所有后续https请求(包括静态文件(都将嵌入该cookie。您需要更新中间件来检查cookie,而不是标头。而且你再也不需要AuthService了。

最新更新