Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
825 views
in Technique[技术] by (71.8m points)

node.js - How to secure my react app api with csurf?

I am trying to add csrf protection to my react app but I am getting an error Invalid token all the time

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);

}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You need to:
1. Configure csrf library on the server. This ensures the library will send the first piece of data attached to the server responses.
2. Use csrf library on the server to generate the second piece of data and attach it to the server response (e.g. HTML form sent to the client). After this step is completed the server response will carry two pieces of CSRF data.
3. On the client take the second piece of data and insert it into the request you are about to send (e.g. the form you are about to submit).

Step 1
So far only the step (1) has been completed. You asked the csrf library to send the first piece of data as a cookie. You could have used a better configuration:

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

It ensures the browser won't allow any JS on the client to touch the first piece of data inside the cookie which is good because there is no legit reason for any script to know what is inside this cookie. Later on, in production and when you use HTTPS, you can optionally add secure: true to the above configuration to make the server refuse to send this cookie over connections that are not secure.

Step 2
To get the second piece of data call csrfToken(). The csrf middleware added another property to Request object for your convenience so it can be called like this: const secondPiece = req.csrfToken(). You can put the second piece of data into the server responce in any way or manner you like: into another cookie with an arbitrary name (except for the _csrf name already taken by the step 1 cookie) or into HTTP header named as you like.

For example this code will put it into another cookie:

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

Step 3
On the client write JS to get the second piece of data and put it into one of the predefined places/locations (inside the request to be sent to the server) where csrf middleware searches for it by default.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...