2017-01-06 11 views
1

Я работаю над образцовым приложением, используя Node.js для серверной стороны и Angular 2 для переднего конца.Приложение Node JS/Angular 2, ForbiddenError: недопустимый токен csrf

Для предотвращения 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» вызывается из моего метода ниже Угловой 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. enter image description here

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

enter image description here

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

ответ

0

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

От the project page:

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. 

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

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

Смежные вопросы