使用 JWT 保护 Express 路线
Posted
技术标签:
【中文标题】使用 JWT 保护 Express 路线【英文标题】:Securing Express route with JWT 【发布时间】:2021-07-28 17:53:46 【问题描述】:我是 JWT 身份验证的新手,我需要保护 Express 路由。在添加身份验证之前,我执行以下操作以使用 Express 返回 html 页面:
var cache = ;
app.get('/my_page', function (req, res)
serveStatic(res, cache, './public/default/my_page.html');
);
其中 serveStatic 是:
var send404 = function (response)
response.writeHead(404, 'Content-Type': 'text/plain');
response.write('Error 404: Resource not found.');
response.end();
var sendFile = function(response, filePath, fileContents)
var mimeType = mime.lookup(path.basename(filePath));
response.writeHead(200, "content-type": mimeType);
response.end(fileContents);
var serveStatic = function(response, cache, absPath)
if (cache[absPath])
sendFile(response, absPath, cache[absPath]);
else
fs.exists(absPath, function(exists)
if (exists)
fs.readFile(absPath, function(err, data)
if (err)
send404(response);
else
cache[absPath] = data; // Cache the file
sendFile(response, absPath, data); // Serve the file
);
else
send404(response);
);
用户点击按钮访问页面:<button type="button" onclick="window.location='my_page'">Go</button>
我添加了如下认证:
// In /middleware/auth file
const jwt = require("jsonwebtoken");
const dotenv = require('dotenv');
dotenv.config();
module.exports = function(req, res, next)
const token = req.header("Authorization");
if (!token)
return res.status(401).json(
message: "Auth Error",
errorCode: 401,
redirectUrl: "/"
);
try
const decoded = jwt.verify(token, process.env.SECRET);
req.user = decoded.user;
next();
catch (e)
res.status(500).send(
message: "Invalid Token",
errorCode: 500,
redirectUrl: "/"
);
;
我把路由管理改成:
const auth = require("./middleware/auth");
app.get('/licenses',
auth,
function (req, res, next)
serveStatic(res, cache, './public/default/my_page.html');
);
我更改了 onclick 按钮以调用从 cookie 中检索 JWT 并将其与请求一起发送的函数。
<button type="button" onclick="openPage()">Go</button>
var openPage= function()
if (document.cookie != "")
var token = getCookie("token");
if (token != "")
$.ajax(
type: "GET",
url: "/my_page",
data: ,
dataType: "json",
beforeSend: function (xhr)
xhr.setRequestHeader('Authorization', token);
,
success: function(msg)
,
error: function($xhr, textStatus, errorThrown)
);
else
console.error('token is empty');
else
console.error('cookie is empty');
身份验证过程很好,但客户端收到一条消息,其中包含 my_page.html 代码在其 responseText 属性中。有没有办法让它表现得像我添加身份验证之前的样子?
【问题讨论】:
【参考方案1】:我认为问题在于,一开始,您将浏览器重定向到 /my_page
端点。所以浏览器接收整个 HTML 网页作为HTTP
请求的payload
并在页面上呈现。然后,您更改 AJAX 请求的行为,允许在不刷新页面的情况下从服务器获取数据。
AJAX 代表异步 javascript 和 XML。简而言之,就是使用 XMLHttpRequest 对象与服务器进行通信。它可以发送和接收各种格式的信息,包括 JSON、XML、HTML 和文本文件。 AJAX 最吸引人的特点是它的“异步”特性,这意味着它可以与服务器通信、交换数据、更新页面而无需刷新页面。 _来自 MDN WebDocs Ajax/Getting Started
您可能会恢复将客户重定向到您之前所做的方式(尽管最好使用锚标记),但这不会解决您的问题。授权中间件将拒绝请求,因为它在 Authentication
标头上找不到 JWT。
尽管如此,从您对 openPage
函数的实现来看,我看到您已经将 JWT 令牌存储在 cookie
中。 Cookie 与每个请求一起发送到服务器。最好尝试修改身份验证中间件以从 cookie 中获取 JWT 令牌,而不是从 Authentication
标头中获取。
【讨论】:
成功了,谢谢。我像以前一样替换了 AJAX 调用,并从 cookie 中检索了令牌。以上是关于使用 JWT 保护 Express 路线的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 JWT 在 Express 中验证单个路由(无代码重复)的多种类型用户的身份验证令牌?