Приложение Node JS/Angular 2, ForbiddenError: недопустимый токен csrf

Я работаю над примером приложения, используя Node.js для серверной части и Angular 2 для внешнего интерфейса.

Чтобы предотвратить атаки CSRF, я использовал промежуточное программное обеспечение csurf. Ниже приведен соответствующий код для установки промежуточного программного обеспечения.

// cookie parser
app.use(cookieParser());

// express session middleware , this should be after cookie parser
app.use(session({secret:'clickclick'}));

app.use(session({ 
secret: 'clickclick',
cookie: {
    path:'/',
    httpOnly:true,
    maxAge:null
}
}));

// CSRF middleware
app.use(csurf());

Ниже маршрут node.js устанавливает заголовок «_csrf»

router.get('/:id/products/:pid' ,  wrap(function *(req , res , next) {

try 
{
    console.log('url' , req.url);
    res.setHeader('_csrf', req.csrfToken());
    let product = yield category.getProduct(req , res , next);
    res.send(product);
}
catch(err) 
{
    res.status(500).send(err);
}

})) 

Вышеупомянутый маршрут '/:id/products/:pid' вызывается из моего нижеприведенного метода службы Angular 2.

// Get Product
GetProduct(id:string, pid:string):Observable<Product> {

    return this.http.get('./categories/' + id + '/products/' + pid)
                    .map(data =>{ let headers:Headers = data.headers; 
                                  this.csrfToken = headers.get('_csrf') ; 
                               return data.json() })
                    .catch(this.handleError);
}

Этот метод назначает заголовок _csrf, возвращенный с сервера, свойству this.csrfToken.

И когда приведенный ниже метод службы отправляет запрос AJAX POST, он использует значение свойства this.csrfToken, установленное указанным выше методом, и устанавливает значение заголовка «_csrf».

// Add an item to cart
 AddTocart(product:Product) 
 {
    let item = { pid:product._id , name:product.name , price:product.price , qty:1 , total:product.price  };   
    //this.cart.push(item);

    // make an AJAX call to save the item in server session
    let url = './cart/add';
    let headers = new Headers({'Content-Type':'application/json' , '_csrf':this.csrfToken});
    let requestOptions = new RequestOptions({headers:headers});

    this.http.post(url , item , requestOptions)
             .map(data => {                                
                            this.cart.push(item);
                          }
             )
             .catch(this.handleError)
             .subscribe( data => { });                

}

Ниже приведен заголовок ответа метода службы GetProduct. введите здесь описание изображения

А ниже — заголовок запроса сервисного метода «AddTocart».

введите здесь описание изображения

Любая идея, что вызывает ошибку «ForbiddenError: недопустимый токен csrf». Пожалуйста, дайте мне знать, если мне нужно предоставить дополнительную информацию или если предоставленная информация неясна.


person refactor    schedule 06.01.2017    source источник
comment
Пожалуйста, опубликуйте ответ на это, если у вас есть ответ. У меня такая же проблема сейчас. Приложение My Express и приложение Angular 6 были развернуты отдельно.   -  person Sherwin Ablaña Dapito    schedule 15.12.2018


Ответы (1)


Я знаю, что это старый вопрос, но я добавляю его сюда на случай, если кто-то наткнется на него в будущем. Работая над аналогичным проектом и столкнувшись с той же ошибкой, я исправил ее, добавив заголовок XSRF-TOKEN в запрос POST со значением, взятым из $.cookie("XSRF-TOKEN") (используя jquery и плагин cookie). Согласно документам, _csrf тоже должен работать.

На странице проекта:

The default value is a function that reads the token from the following locations, in order:

req.body._csrf - typically generated by the body-parser module.
req.query._csrf - a built-in from Express.js to read from the URL query string.
req.headers['csrf-token'] - the CSRF-Token HTTP request header.
req.headers['xsrf-token'] - the XSRF-Token HTTP request header.
req.headers['x-csrf-token'] - the X-CSRF-Token HTTP request header.
req.headers['x-xsrf-token'] - the X-XSRF-Token HTTP request header.

Насколько я могу судить, ошибка возникает из-за запросов POST/PUT, включая правильные файлы cookie, но nodejs/csurf их там не ищет.

В вашем конкретном случае _csrf должно быть в теле запроса вместе с товарами в корзине, или заголовок должен быть переименован в csrf-token, или один из других вариантов.

person Stephan Pieterse    schedule 05.09.2017