如何使用 csurf 保护我的 react app api?

IT技术 node.js reactjs express csrf
2021-04-12 02:06:53

我正在尝试向我的 React 应用程序添加 csrf 保护,但我一直收到错误无效令牌

import bodyParser from 'body-parser';
import cookieSession from 'cookie-session';
import passport from 'passport';
import csrf from 'csurf'
import config from '../../config'
import AuthRoutes from "./routes/AuthRoutes";

/* Test only */
import cookieParser from 'cookie-parser';


const session = cookieSession({
    maxAge:24 * 60 * 60 * 1000,
    keys:[config.COOKIE_KEY],
    name:'authentication',

});



export default app => {

    app.use(bodyParser.urlencoded({
        extended: true
    }));
    app.use(bodyParser.json());
    app.use(session);
    app.use(passport.initialize());
    app.use(passport.session());

    /* Test */
    app.use(cookieParser());
    app.use(csrf({ cookie: true }));

    app.use(function (err, req, res, next) {
        if (err.code !== 'EBADCSRFTOKEN') return next(err)

        // handle CSRF token errors here
        res.status(403)
        res.send('form tampered with')
    })

    /*Passport Config*/
    require('../../services');

    /* Register, Login these are routes i want to protect */
    AuthRoutes(app);

}
2个回答

您需要:
1.csrf在服务器上配置库。这确保库将发送附加到服务器响应的第一条数据。
2. 使用csrf服务器上的库生成第二条数据并将其附加到服务器响应(例如发送到客户端的 HTML 表单)。此步骤完成后,服务器响应将携带两条 CSRF 数据。
3. 在客户端获取第二条数据并将其插入到您将要发送的请求中(例如您将要提交的表单)。

步骤1
至此只完成了步骤(1)。您要求csrf图书馆将第一条数据作为 cookie 发送。您可以使用更好的配置:

app.use(csrf({cookie: {
    httpOnly: true,
}}));

它确保浏览器不会允许客户端上的任何 JS 接触 cookie 中的第一条数据,这很好,因为任何脚本都没有合法的理由知道这个 cookie 中的内容。稍后,在生产中和使用 HTTPS 时,您可以选择添加secure: true到上述配置中,使服务器拒绝通过不安全的连接发送此 cookie。

Step 2
获取第二条数据调用csrfToken()csrf中间件添加另一个属性Request对象为您提供方便,因此它可以被称为是这样的:const secondPiece = req.csrfToken()您可以以您喜欢的任何方式或方式将第二条数据放入服务器响应中:放入具有任意名称的另一个 cookie(_csrf步骤 1 cookie 已采用名称除外)或放入您喜欢的 HTTP 标头中。

例如,此代码会将其放入另一个 cookie:

res.cookie('XSRF-TOKEN', req.csrfToken());

步骤 3
在客户端编写 JS 以获取第二条数据并将其放入预定义的位置/位置之一(在要发送到服务器的请求内),默认情况下csrf中间件会在其中搜索它。

将令牌从服务器发送到客户端作为 cookie(必须是 httpOnly: false 否则客户端无法将其抓取到头中)比作为端点响应的正文更安全吗?
2021-05-23 02:06:53

以防万一,任何解决方案都不起作用。

由于 cookie 的命名不正确,我只进行了几天的调试。确保为您的 cookie 命名XSRF-COOKIE(注意它使用了-符号),因为我使用下划线错误地命名了我的 cookie XSRF_COOKIE,这让我的屁股好几天了。