我正在创建一个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了。