社区的403报错也太详细了吧 Nodejs版
社区的403报错也太详细了吧 Nodejs版
刚在退出登录时,响应了403错误,但是错误信息里包含了很多后台路径。
这里是重现方法: 1、登录 2、打开firebug - 网络 3、页面右上角,点击退出 4、在firebug - 网络中重新发送/signout请求
下面是响应的部分内容:
_method=post&_csrf=MsdHCW15DVoGXFOGJaNbQk%2FogEpqmiElcpmiM%3D
HTTP/1.1 403 Forbidden
Server: nginx/1.1.19
Date: Mon, 26 May 2014 02:46:49 GMT
Content-Type: text/html
Transfer-Encoding: chunked
Connection: keep-alive
X-Powered-By: Express
Vary: Accept-Encoding
X-Response-Time: 6ms
1f86
Error: invalid csrf token
at createToken (/home/ubuntu/nodeclub/node_modules/csurf/index.js:77:19)
at Layer.<anonymous> (/home/ubuntu/nodeclub/node_modules/csurf/index.js:51:24)
at Layer.eval [as handle] (<anonymous>:10:14)
at trim_prefix (/home/ubuntu/nodeclub/node_modules/express/lib/router/index.js:230:15)
at c (/home/ubuntu/nodeclub/node_modules/express/lib/router/index.js:198:9)
at Function.proto.process_params (/home/ubuntu/nodeclub/node_modules/express/lib/router/index.js:
…
社区的403报错也太详细了吧 Nodejs版
最近在处理一个 Node.js 应用中的问题时,我在退出登录的过程中遇到了一个 403 错误。这个错误不仅阻止了正常操作,还暴露了一些敏感的后台路径信息,这显然不是我们希望看到的情况。
重现步骤:
- 登录:首先确保你已经成功登录到系统。
- 打开 Firebug 或开发者工具:进入网络监控界面。
- 点击退出:在页面右上角找到退出按钮并点击。
- 重新发送 /signout 请求:在 Firebug 的网络面板中,找到
/signout
请求,并重新发送该请求。
响应详情:
当重新发送 /signout
请求时,服务器返回了一个 403 Forbidden 错误。下面是响应的具体内容:
HTTP/1.1 403 Forbidden
Server: nginx/1.1.19
Date: Mon, 26 May 2014 02:46:49 GMT
Content-Type: text/html
Transfer-Encoding: chunked
Connection: keep-alive
X-Powered-By: Express
Vary: Accept-Encoding
X-Response-Time: 6ms
1f86
Error: invalid csrf token
at createToken (/home/ubuntu/nodeclub/node_modules/csurf/index.js:77:19)
at Layer.<anonymous> (/home/ubuntu/nodeclub/node_modules/csurf/index.js:51:24)
at Layer.handle [as handle_request] (<anonymous>:10:14)
at trim_prefix (/home/ubuntu/nodeclub/node_modules/express/lib/router/index.js:230:15)
at c (/home/ubuntu/nodeclub/node_modules/express/lib/router/index.js:198:9)
at Function.proto.process_params (/home/ubuntu/nodeclub/node_modules/express/lib/router/index.js:
......
分析与解决:
从响应内容可以看出,错误原因是 invalid csrf token
。CSRF(Cross-Site Request Forgery)是一种常见的安全攻击方式,通过伪造请求来执行恶意操作。为了防止这种攻击,我们在应用中使用了 csurf
中间件来生成和验证 CSRF 令牌。
解决方案:
- 检查 CSRF 令牌配置:确保 CSRF 令牌正确生成并在表单或请求头中传递。
- 更新中间件配置:确保
csurf
中间件配置正确,例如设置为cookie: true
或其他合适的配置。 - 检查前端逻辑:确保前端在发送请求时携带正确的 CSRF 令牌。
示例代码:
const express = require('express');
const csrf = require('csurf');
// 创建 Express 应用实例
const app = express();
// 使用 csurf 中间件
app.use(csrf({ cookie: true }));
// 登出路由
app.get('/logout', (req, res) => {
req.logout();
res.redirect('/');
});
// 处理错误
app.use((err, req, res, next) => {
if (err.code === 'EBADCSRFTOKEN') {
return res.status(403).send('Invalid CSRF token');
}
next(err);
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
在这个示例中,我们配置了 csurf
中间件,并处理了 EBADCSRFTOKEN
错误,以确保用户在遇到无效的 CSRF 令牌时能够得到明确的反馈。
根据你提供的信息,你的应用在处理 /signout
请求时返回了 403 错误,并且错误信息提示 invalid csrf token
。这表明在请求中缺少或不正确的 CSRF 令牌导致了请求被拒绝。
解决方案
- 确保 CSRF 令牌正确传输:确保在发起请求时正确传递 CSRF 令牌。通常,CSRF 令牌会包含在表单数据或 HTTP 头中。对于
POST
请求,可以通过添加 CSRF 令牌到请求体中来解决。
示例代码:
const axios = require('axios');
const express = require('express');
const csurf = require('csurf');
const app = express();
app.use(express.urlencoded({ extended: true }));
app.use(csurf({ cookie: true }));
app.get('/logout', (req, res) => {
res.send(`
<form action="/signout" method="POST">
<input type="hidden" name="_csrf" value="${req.csrfToken()}">
<button type="submit">Logout</button>
</form>
`);
});
app.post('/signout', (req, res) => {
// 处理登出逻辑
res.send("Logged out successfully.");
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
解释
- 引入依赖:使用
express
和csurf
模块。 - 中间件配置:使用
express.urlencoded
解析表单数据,并使用csurf
中间件来生成和验证 CSRF 令牌。 - GET 请求:提供一个获取 CSRF 令牌的 HTML 表单,在表单中隐藏地传递 CSRF 令牌。
- POST 请求:处理
/signout
路由,确保请求中包含 CSRF 令牌。
通过这种方式,你可以确保每次请求都包含有效的 CSRF 令牌,从而避免 403 错误。